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: [PATCH] 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 ++++++++++++-------
 .../newview/llfloaterimnearbychathandler.cpp  |  5 ----
 indra/newview/llfloaterimsessiontab.cpp       |  2 +-
 indra/newview/llimview.cpp                    |  6 +++++
 6 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 261f53d6b69..9b54a7a4675 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 1b1d61e6d63..a696fbdb478 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 a04b8d79d60..3a80491dae8 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 d9c461e8360..903c903381e 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 6e58a66bcd6..efc7be6dd6d 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 e5dda7e8d86..b6fd3ec9c87 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");
     }
 }
-- 
GitLab