From d2d6af3dfa0f8a423016f5972d44a9721b1be1ee Mon Sep 17 00:00:00 2001
From: Dmitry Zaporozhan <dzaporozhan@productengine.com>
Date: Mon, 8 Feb 2010 18:06:41 +0200
Subject: [PATCH] Fixed critical bug EXT-4970 - Inventory offers by scripted
 objects are discarded when offered objects got the same name. Had to do minor
 refactoring of LLScripFloaterManager in order to fix this issue.

--HG--
branch : product-engine
---
 indra/newview/llchiclet.cpp                   |  21 +-
 indra/newview/llscriptfloater.cpp             | 261 +++++++++---------
 indra/newview/llscriptfloater.h               |  45 +--
 indra/newview/llsyswellwindow.cpp             | 112 ++------
 indra/newview/llsyswellwindow.h               |  23 +-
 indra/newview/llviewermessage.cpp             |   9 -
 .../xui/en/panel_active_object_row.xml        |   4 -
 7 files changed, 188 insertions(+), 287 deletions(-)

diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index db804c7c8b5..8efa814a2eb 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -1159,10 +1159,10 @@ void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
 
 void object_chiclet_callback(const LLSD& data)
 {
-	LLUUID object_id = data["object_id"];
+	LLUUID notification_id = data["notification_id"];
 	bool new_message = data["new_message"];
 
-	std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(object_id);
+	std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(notification_id);
 	std::list<LLChiclet *>::iterator iter;
 	for (iter = chiclets.begin(); iter != chiclets.end(); iter++)
 	{
@@ -1894,12 +1894,8 @@ void LLScriptChiclet::setSessionId(const LLUUID& session_id)
 	setShowNewMessagesIcon( getSessionId() != session_id );
 
 	LLIMChiclet::setSessionId(session_id);
-	LLUUID notification_id = LLScriptFloaterManager::getInstance()->findNotificationId(session_id);
-	LLNotificationPtr notification = LLNotifications::getInstance()->find(notification_id);
-	if(notification)
-	{
-		setToolTip(notification->getSubstitutions()["TITLE"].asString());
-	}
+
+	setToolTip(LLScriptFloaterManager::getObjectName(session_id));
 }
 
 void LLScriptChiclet::setCounter(S32 counter)
@@ -1948,13 +1944,10 @@ void LLInvOfferChiclet::setSessionId(const LLUUID& session_id)
 {
 	setShowNewMessagesIcon( getSessionId() != session_id );
 
+	setToolTip(LLScriptFloaterManager::getObjectName(session_id));
+
 	LLIMChiclet::setSessionId(session_id);
-	LLUUID notification_id = LLScriptFloaterManager::getInstance()->findNotificationId(session_id);
-	LLNotificationPtr notification = LLNotifications::getInstance()->find(notification_id);
-	if(notification)
-	{
-		setToolTip(notification->getSubstitutions()["TITLE"].asString());
-	}
+	LLNotificationPtr notification = LLNotifications::getInstance()->find(session_id);
 
 	if ( notification && notification->getName() == INVENTORY_USER_OFFER )
 	{
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index 0d9cf06bc34..465d36b8de5 100644
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -38,9 +38,11 @@
 #include "llchiclet.h"
 #include "llfloaterreg.h"
 #include "llnotifications.h"
+#include "llnotificationsutil.h"
 #include "llscreenchannel.h"
 #include "llsyswellwindow.h"
 #include "lltoastnotifypanel.h"
+#include "lltrans.h"
 #include "llviewerwindow.h"
 #include "llimfloater.h"
 
@@ -70,12 +72,11 @@ LLScriptFloater::LLScriptFloater(const LLSD& key)
 	setOverlapsScreenChannel(true);
 }
 
-bool LLScriptFloater::toggle(const LLUUID& object_id)
+bool LLScriptFloater::toggle(const LLUUID& notification_id)
 {
 	// Force chiclet toggle on here because first onFocusReceived() will not toggle it on.
-	LLBottomTray::getInstance()->getChicletPanel()->setChicletToggleState(object_id, true);
+	LLBottomTray::getInstance()->getChicletPanel()->setChicletToggleState(notification_id, true);
 
-	LLUUID notification_id = LLScriptFloaterManager::getInstance()->findNotificationId(object_id);
 	LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", notification_id);
 
 	// show existing floater
@@ -96,22 +97,21 @@ bool LLScriptFloater::toggle(const LLUUID& object_id)
 	// create and show new floater
 	else
 	{
-		show(object_id);
+		show(notification_id);
 		return true;
 	}
 }
 
-LLScriptFloater* LLScriptFloater::show(const LLUUID& object_id)
+LLScriptFloater* LLScriptFloater::show(const LLUUID& notification_id)
 {
-	LLUUID notification_id = LLScriptFloaterManager::getInstance()->findNotificationId(object_id);
-	
 	LLScriptFloater* floater = LLFloaterReg::showTypedInstance<LLScriptFloater>("script_floater", notification_id);
-	floater->setObjectId(object_id);
-	floater->createForm(object_id);
+
+	floater->setNotificationId(notification_id);
+	floater->createForm(notification_id);
 
 	if (floater->getDockControl() == NULL)
 	{
-		LLChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(object_id);
+		LLChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(notification_id);
 		if (chiclet == NULL)
 		{
 			llerror("Dock chiclet for LLScriptFloater doesn't exist", 0);
@@ -133,7 +133,7 @@ void LLScriptFloater::getAllowedRect(LLRect& rect)
 	rect = gViewerWindow->getWorldViewRectRaw();
 }
 
-void LLScriptFloater::createForm(const LLUUID& object_id)
+void LLScriptFloater::createForm(const LLUUID& notification_id)
 {
 	// delete old form
 	if(mScriptForm)
@@ -142,8 +142,7 @@ void LLScriptFloater::createForm(const LLUUID& object_id)
 		mScriptForm->die();
 	}
 
-	LLNotificationPtr notification = LLNotifications::getInstance()->find(
-		LLScriptFloaterManager::getInstance()->findNotificationId(object_id));
+	LLNotificationPtr notification = LLNotifications::getInstance()->find(notification_id);
 	if(NULL == notification)
 	{
 		return;
@@ -165,9 +164,9 @@ void LLScriptFloater::createForm(const LLUUID& object_id)
 
 void LLScriptFloater::onClose(bool app_quitting)
 {
-	if(getObjectId().notNull())
+	if(getNotificationId().notNull())
 	{
-		LLScriptFloaterManager::getInstance()->removeNotificationByObjectId(getObjectId());
+		LLScriptFloaterManager::getInstance()->onRemoveNotification(getNotificationId());
 	}
 }
 
@@ -186,7 +185,7 @@ void LLScriptFloater::setVisible(BOOL visible)
 
 	if(!visible)
 	{
-		LLIMChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getObjectId());
+		LLIMChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getNotificationId());
 		if(chiclet)
 		{
 			chiclet->setToggleState(false);
@@ -196,10 +195,10 @@ void LLScriptFloater::setVisible(BOOL visible)
 
 void LLScriptFloater::onMouseDown()
 {
-	if(getObjectId().notNull())
+	if(getNotificationId().notNull())
 	{
 		// Remove new message icon
-		LLIMChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getObjectId());
+		LLIMChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getNotificationId());
 		if (chiclet == NULL)
 		{
 			llerror("Dock chiclet for LLScriptFloater doesn't exist", 0);
@@ -213,15 +212,18 @@ void LLScriptFloater::onMouseDown()
 
 void LLScriptFloater::onFocusLost()
 {
-	LLBottomTray::getInstance()->getChicletPanel()->setChicletToggleState(getObjectId(), false);
+	if(getNotificationId().notNull())
+	{
+		LLBottomTray::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), false);
+	}
 }
 
 void LLScriptFloater::onFocusReceived()
 {
 	// first focus will be received before setObjectId() call - don't toggle chiclet
-	if(getObjectId().notNull())
+	if(getNotificationId().notNull())
 	{
-		LLBottomTray::getInstance()->getChicletPanel()->setChicletToggleState(getObjectId(), true);
+		LLBottomTray::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), true);
 	}
 }
 
@@ -246,200 +248,203 @@ void LLScriptFloater::hideToastsIfNeeded()
 
 void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
 {
-	// get scripted Object's ID
-	LLUUID object_id = notification_id_to_object_id(notification_id);
-	if(object_id.isNull())
+	if(notification_id.isNull())
 	{
-		llwarns << "Invalid notification, no object id" << llendl;
+		llwarns << "Invalid notification ID" << llendl;
 		return;
 	}
 
+	// get scripted Object's ID
+	LLUUID object_id = notification_id_to_object_id(notification_id);
+	
 	// Need to indicate of "new message" for object chiclets according to requirements
 	// specified in the Message Bar design specification. See EXT-3142.
 	bool set_new_message = false;
+	EObjectType obj_type = getObjectType(notification_id);
 
-	// If an Object spawns more-than-one floater, only the newest one is shown. 
-	// The previous is automatically closed.
-	script_notification_map_t::iterator it = mNotifications.find(object_id);
-	if(it != mNotifications.end())
+	// LLDialog can spawn only one instance, LLLoadURL and LLGiveInventory can spawn unlimited number of instances
+	if(OBJ_SCRIPT == obj_type)
 	{
-		LLIMChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(object_id);
-		if(chiclet)
+		// If an Object spawns more-than-one floater, only the newest one is shown. 
+		// The previous is automatically closed.
+		script_notification_map_t::const_iterator it = findUsingObjectId(object_id);
+		if(it != mNotifications.end())
 		{
-			// Pass the new_message icon state further.
-			set_new_message = chiclet->getShowNewMessagesIcon();
-		}
+			LLIMChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(it->first);
+			if(chiclet)
+			{
+				// Pass the new_message icon state further.
+				set_new_message = chiclet->getShowNewMessagesIcon();
+			}
 
-		LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->second.notification_id);
-		if(floater)
-		{
-			// Generate chiclet with a "new message" indicator if a docked window was opened but not in focus. See EXT-3142.
-			set_new_message |= !floater->hasFocus();
-		}
+			LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->first);
+			if(floater)
+			{
+				// Generate chiclet with a "new message" indicator if a docked window was opened but not in focus. See EXT-3142.
+				set_new_message |= !floater->hasFocus();
+			}
 
-		onRemoveNotification(it->second.notification_id);
+			onRemoveNotification(it->first);
+		}
 	}
 
-	LLNotificationData nd = {notification_id};
-	mNotifications.insert(std::make_pair(object_id, nd));
+	mNotifications.insert(std::make_pair(notification_id, object_id));
 
 	// Create inventory offer chiclet for offer type notifications
-	LLNotificationPtr notification = LLNotifications::getInstance()->find(notification_id);
-	if( notification && notification->getType() == "offer" )
+	if( OBJ_GIVE_INVENTORY == obj_type )
 	{
-		LLBottomTray::instance().getChicletPanel()->createChiclet<LLInvOfferChiclet>(object_id);
+		LLBottomTray::instance().getChicletPanel()->createChiclet<LLInvOfferChiclet>(notification_id);
 	}
 	else
 	{
-		LLBottomTray::getInstance()->getChicletPanel()->createChiclet<LLScriptChiclet>(object_id);
+		LLBottomTray::getInstance()->getChicletPanel()->createChiclet<LLScriptChiclet>(notification_id);
 	}
 
-	LLIMWellWindow::getInstance()->addObjectRow(object_id, set_new_message);
+	LLIMWellWindow::getInstance()->addObjectRow(notification_id, set_new_message);
 
 	LLSD data;
-	data["object_id"] = object_id;
+	data["notification_id"] = notification_id;
 	data["new_message"] = set_new_message;
 	data["unread"] = 1; // each object has got only one floater
 	mNewObjectSignal(data);
 
-	toggleScriptFloater(object_id, set_new_message);
+	toggleScriptFloater(notification_id, set_new_message);
 }
 
 void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id)
 {
-	LLUUID object_id = findObjectId(notification_id);
-	if(object_id.isNull())
+	if(notification_id.isNull())
 	{
-		llwarns << "Invalid notification, no object id" << llendl;
+		llwarns << "Invalid notification ID" << llendl;
 		return;
 	}
 
-	using namespace LLNotificationsUI;
-
-	// remove related toast
-	LLUUID channel_id(gSavedSettings.getString("NotificationChannelUUID"));
-	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>
-		(LLChannelManager::getInstance()->findChannelByID(channel_id));
-	LLUUID n_toast_id = findNotificationToastId(object_id);
-	if(channel && n_toast_id.notNull())
-	{
-		channel->killToastByNotificationID(n_toast_id);
-	}
-
 	// remove related chiclet
-	LLBottomTray::getInstance()->getChicletPanel()->removeChiclet(object_id);
+	LLBottomTray::getInstance()->getChicletPanel()->removeChiclet(notification_id);
 
-	LLIMWellWindow::getInstance()->removeObjectRow(object_id);
+	LLIMWellWindow::getInstance()->removeObjectRow(notification_id);
 
 	// close floater
 	LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", notification_id);
 	if(floater)
 	{
-		floater->setObjectId(LLUUID::null);
+		floater->setNotificationId(LLUUID::null);
 		floater->closeFloater();
 	}
 
-	mNotifications.erase(object_id);
-}
-
-void LLScriptFloaterManager::removeNotificationByObjectId(const LLUUID& object_id)
-{
-	// Check we have not removed notification yet
-	LLNotificationPtr notification = LLNotifications::getInstance()->find(
-		findNotificationId(object_id));
-	if(notification)
-	{
-		onRemoveNotification(notification->getID());
-	}
+	mNotifications.erase(notification_id);
 }
 
-void LLScriptFloaterManager::toggleScriptFloater(const LLUUID& object_id, bool set_new_message)
+void LLScriptFloaterManager::toggleScriptFloater(const LLUUID& notification_id, bool set_new_message)
 {
-	// kill toast
-	using namespace LLNotificationsUI;
-	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->findChannelByID(
-		LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-	if(channel)
-	{
-		channel->killToastByNotificationID(findNotificationToastId(object_id));
-	}
-
 	LLSD data;
-	data["object_id"] = object_id;
+	data["notification_id"] = notification_id;
 	data["new_message"] = set_new_message;
 	mToggleFloaterSignal(data);
 
 	// toggle floater
-	LLScriptFloater::toggle(object_id);
+	LLScriptFloater::toggle(notification_id);
 }
 
-void LLScriptFloaterManager::setNotificationToastId(const LLUUID& object_id, const LLUUID& notification_id)
+LLUUID LLScriptFloaterManager::findObjectId(const LLUUID& notification_id)
 {
-	script_notification_map_t::iterator it = mNotifications.find(object_id);
+	script_notification_map_t::const_iterator it = mNotifications.find(notification_id);
 	if(mNotifications.end() != it)
 	{
-		it->second.toast_notification_id = notification_id;
+		return it->second;
 	}
+	return LLUUID::null;
 }
 
-LLUUID LLScriptFloaterManager::findObjectId(const LLUUID& notification_id)
+LLUUID LLScriptFloaterManager::findNotificationId(const LLUUID& object_id)
 {
-	if(notification_id.notNull())
+	if(object_id.notNull())
 	{
-		script_notification_map_t::const_iterator it = mNotifications.begin();
-		for(; mNotifications.end() != it; ++it)
+		script_notification_map_t::const_iterator it = findUsingObjectId(object_id);
+		if(mNotifications.end() != it)
 		{
-			if(notification_id == it->second.notification_id)
-			{
-				return it->first;
-			}
+			return it->first;
 		}
 	}
 	return LLUUID::null;
 }
 
-LLUUID LLScriptFloaterManager::findNotificationId(const LLUUID& object_id)
+// static
+LLScriptFloaterManager::EObjectType LLScriptFloaterManager::getObjectType(const LLUUID& notification_id)
 {
-	script_notification_map_t::const_iterator it = mNotifications.find(object_id);
-	if(mNotifications.end() != it)
+	if(notification_id.isNull())
 	{
-		return it->second.notification_id;
+		llwarns << "Invalid notification ID" << llendl;
+		return OBJ_UNKNOWN;
 	}
-	return LLUUID::null;
-}
 
-LLUUID LLScriptFloaterManager::findNotificationToastId(const LLUUID& object_id)
-{
-	script_notification_map_t::const_iterator it = mNotifications.find(object_id);
-	if(mNotifications.end() != it)
+	static const object_type_map TYPE_MAP = initObjectTypeMap();
+
+	LLNotificationPtr notification = LLNotificationsUtil::find(notification_id);
+	object_type_map::const_iterator it = TYPE_MAP.find(notification->getName());
+	if(it != TYPE_MAP.end())
 	{
-		return it->second.toast_notification_id;
+		return it->second;
 	}
-	return LLUUID::null;
+
+	llwarns << "Unknown object type" << llendl;
+	return OBJ_UNKNOWN;
 }
 
-//static
-void LLScriptFloaterManager::onToastButtonClick(const LLSD&notification, const LLSD&response)
+// static
+std::string LLScriptFloaterManager::getObjectName(const LLUUID& notification_id)
 {
-	S32 option = LLNotification::getSelectedOption(notification, response);
-	LLUUID object_id = notification["payload"]["object_id"].asUUID();
+	using namespace LLNotificationsUI;
+	LLNotificationPtr notification = LLNotifications::getInstance()->find(notification_id);
+	if(!notification)
+	{
+		llwarns << "Invalid notification" << llendl;
+		return LLStringUtil::null;
+	}
+
+	std::string text;
 
-	switch(option)
+	switch(LLScriptFloaterManager::getObjectType(notification_id))
 	{
-	case 0: // "Open"
-		LLScriptFloaterManager::getInstance()->toggleScriptFloater(object_id);
+	case LLScriptFloaterManager::OBJ_SCRIPT:
+		text = notification->getSubstitutions()["TITLE"].asString();
 		break;
-	case 1: // "Ignore"
-		LLScriptFloaterManager::getInstance()->removeNotificationByObjectId(object_id);
+	case LLScriptFloaterManager::OBJ_LOAD_URL:
+		text = notification->getSubstitutions()["OBJECTNAME"].asString();
 		break;
-	case 2: // "Block"
-		LLMuteList::getInstance()->add(LLMute(object_id, notification["substitutions"]["TITLE"], LLMute::OBJECT));
-		LLScriptFloaterManager::getInstance()->removeNotificationByObjectId(object_id);
+	case LLScriptFloaterManager::OBJ_GIVE_INVENTORY:
+		text = notification->getSubstitutions()["NAME"].asString();
 		break;
 	default:
-		llwarns << "Unexpected value" << llendl;
+		text = LLTrans::getString("object");
 		break;
 	}
+
+	return text;
+}
+
+//static
+LLScriptFloaterManager::object_type_map LLScriptFloaterManager::initObjectTypeMap()
+{
+	object_type_map type_map;
+	type_map["ScriptDialog"] = OBJ_SCRIPT;
+	type_map["ScriptDialogGroup"] = OBJ_SCRIPT;
+	type_map["LoadWebPage"] = OBJ_LOAD_URL;
+	type_map["ObjectGiveItem"] = OBJ_GIVE_INVENTORY;
+	return type_map;
+}
+
+LLScriptFloaterManager::script_notification_map_t::const_iterator LLScriptFloaterManager::findUsingObjectId(const LLUUID& object_id)
+{
+	script_notification_map_t::const_iterator it = mNotifications.begin();
+	for(; mNotifications.end() != it; ++it)
+	{
+		if(object_id == it->second)
+		{
+			return it;
+		}
+	}
+	return mNotifications.end();
 }
 
 // EOF
diff --git a/indra/newview/llscriptfloater.h b/indra/newview/llscriptfloater.h
index f86605c5d1d..f7efff83f95 100644
--- a/indra/newview/llscriptfloater.h
+++ b/indra/newview/llscriptfloater.h
@@ -48,6 +48,15 @@ class LLScriptFloaterManager : public LLSingleton<LLScriptFloaterManager>
 	// know how script notifications should look like.
 public:
 
+	typedef enum e_object_type
+	{
+		OBJ_SCRIPT,
+		OBJ_GIVE_INVENTORY,
+		OBJ_LOAD_URL,
+
+		OBJ_UNKNOWN
+	}EObjectType;
+
 	/**
 	 * Handles new notifications.
 	 * Saves notification and object ids, removes old notification if needed, creates script chiclet
@@ -61,11 +70,6 @@ class LLScriptFloaterManager : public LLSingleton<LLScriptFloaterManager>
 	 */
 	void onRemoveNotification(const LLUUID& notification_id);
 
-	/**
-	 * Wrapper for onRemoveNotification, removes notification by object id.
-	 */
-	void removeNotificationByObjectId(const LLUUID& object_id);
-
 	/**
 	 * Toggles script floater.
 	 * Removes "new message" icon from chiclet and removes notification toast.
@@ -76,12 +80,9 @@ class LLScriptFloaterManager : public LLSingleton<LLScriptFloaterManager>
 
 	LLUUID findNotificationId(const LLUUID& object_id);
 
-	LLUUID findNotificationToastId(const LLUUID& object_id);
+	static EObjectType getObjectType(const LLUUID& notification_id);
 
-	/**
-	 * Associate notification toast id with object id.
-	 */
-	void setNotificationToastId(const LLUUID& object_id, const LLUUID& notification_id);
+	static std::string getObjectName(const LLUUID& notification_id);
 
 	/**
 	* Callback for notification toast buttons.
@@ -93,16 +94,18 @@ class LLScriptFloaterManager : public LLSingleton<LLScriptFloaterManager>
 	boost::signals2::connection addNewObjectCallback(const object_signal_t::slot_type& cb) { return mNewObjectSignal.connect(cb); }
 	boost::signals2::connection addToggleObjectFloaterCallback(const object_signal_t::slot_type& cb) { return mToggleFloaterSignal.connect(cb); }
 
-private:
+protected:
 
-	struct LLNotificationData
-	{
-		LLUUID notification_id;
-		LLUUID toast_notification_id;
-	};
+	typedef std::map<std::string, EObjectType> object_type_map;
+
+	static object_type_map initObjectTypeMap();
 
-	// <object_id, notification_data>
-	typedef std::map<LLUUID, LLNotificationData> script_notification_map_t;
+	// <notification_id, object_id>
+	typedef std::map<LLUUID, LLUUID> script_notification_map_t;
+
+	script_notification_map_t::const_iterator findUsingObjectId(const LLUUID& object_id);
+
+private:
 
 	script_notification_map_t mNotifications;
 
@@ -136,9 +139,9 @@ class LLScriptFloater : public LLDockableFloater
 	 */
 	static LLScriptFloater* show(const LLUUID& object_id);
 
-	const LLUUID& getObjectId() { return mObjectId; }
+	const LLUUID& getNotificationId() { return mNotificationId; }
 
-	void setObjectId(const LLUUID& id) { mObjectId = id; }
+	void setNotificationId(const LLUUID& id) { mNotificationId = id; }
 
 	/**
 	 * Close notification if script floater is closed.
@@ -180,7 +183,7 @@ class LLScriptFloater : public LLDockableFloater
 
 private:
 	LLToastNotifyPanel* mScriptForm;
-	LLUUID mObjectId;
+	LLUUID mNotificationId;
 };
 
 #endif //LL_SCRIPTFLOATER_H
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index ba15053381c..4d1718be6ae 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -418,16 +418,16 @@ BOOL LLIMWellWindow::RowPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
 /*         ObjectRowPanel implementation                                */
 /************************************************************************/
 
-LLIMWellWindow::ObjectRowPanel::ObjectRowPanel(const LLUUID& object_id, bool new_message/* = false*/)
+LLIMWellWindow::ObjectRowPanel::ObjectRowPanel(const LLUUID& notification_id, bool new_message/* = false*/)
  : LLPanel()
  , mChiclet(NULL)
 {
 	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_active_object_row.xml", NULL);
 
-	initChiclet(object_id);
+	initChiclet(notification_id);
 
 	LLTextBox* obj_name = getChild<LLTextBox>("object_name");
-	obj_name->setValue(getObjectName(object_id));
+	obj_name->setValue(LLScriptFloaterManager::getObjectName(notification_id));
 
 	mCloseBtn = getChild<LLButton>("hide_btn");
 	mCloseBtn->setCommitCallback(boost::bind(&LLIMWellWindow::ObjectRowPanel::onClosePanel, this));
@@ -438,90 +438,18 @@ LLIMWellWindow::ObjectRowPanel::~ObjectRowPanel()
 {
 }
 
-std::string LLIMWellWindow::ObjectRowPanel::getObjectName(const LLUUID& object_id)
-{
-	using namespace LLNotificationsUI;
-	LLUUID notification_id = LLScriptFloaterManager::getInstance()->findNotificationId(object_id);
-	LLNotificationPtr notification = LLNotifications::getInstance()->find(notification_id);
-	if(!notification)
-	{
-		llwarns << "Invalid notification" << llendl;
-		return LLStringUtil::null;
-	}
-
-	std::string text;
-
-	switch(getObjectType(notification))
-	{
-	case OBJ_SCRIPT:
-		text = notification->getSubstitutions()["TITLE"].asString();
-		break;
-	case OBJ_LOAD_URL:
-		text = notification->getSubstitutions()["OBJECTNAME"].asString();
-		break;
-	case OBJ_GIVE_INVENTORY:
-		text = notification->getSubstitutions()["NAME"].asString();
-		break;
-	default:
-		text = getString("unknown_obj");
-		break;
-	}
-
-	return text;
-}
-
 //---------------------------------------------------------------------------------
 void LLIMWellWindow::ObjectRowPanel::onClosePanel()
 {
-	LLScriptFloaterManager::getInstance()->removeNotificationByObjectId(mChiclet->getSessionId());
-}
-
-//static
-LLIMWellWindow::ObjectRowPanel::object_type_map LLIMWellWindow::ObjectRowPanel::initObjectTypeMap()
-{
-	object_type_map type_map;
-	type_map["ScriptDialog"] = OBJ_SCRIPT;
-	type_map["LoadWebPage"] = OBJ_LOAD_URL;
-	type_map["ObjectGiveItem"] = OBJ_GIVE_INVENTORY;
-	return type_map;
-}
-
-// static
-LLIMWellWindow::ObjectRowPanel::EObjectType LLIMWellWindow::ObjectRowPanel::getObjectType(const LLNotificationPtr& notification)
-{
-	if(!notification)
-	{
-		llwarns << "Invalid notification" << llendl;
-		return OBJ_UNKNOWN;
-	}
-
-	static object_type_map type_map = initObjectTypeMap();
-	std::string name = notification->getName();
-	object_type_map::const_iterator it = type_map.find(name);
-	if(it != type_map.end())
-	{
-		return it->second;
-	}
-
-	llwarns << "Unknown object type" << llendl;
-	return OBJ_UNKNOWN;
+	LLScriptFloaterManager::getInstance()->onRemoveNotification(mChiclet->getSessionId());
 }
 
-void LLIMWellWindow::ObjectRowPanel::initChiclet(const LLUUID& object_id, bool new_message/* = false*/)
+void LLIMWellWindow::ObjectRowPanel::initChiclet(const LLUUID& notification_id, bool new_message/* = false*/)
 {
-	using namespace LLNotificationsUI;
-	LLUUID notification_id = LLScriptFloaterManager::getInstance()->findNotificationId(object_id);
-	LLNotificationPtr notification = LLNotifications::getInstance()->find(notification_id);
-	if(!notification)
-	{
-		llwarns << "Invalid notification" << llendl;
-		return;
-	}
-
 	// Choose which of the pre-created chiclets to use.
-	switch(getObjectType(notification))
+	switch(LLScriptFloaterManager::getObjectType(notification_id))
 	{
-	case OBJ_GIVE_INVENTORY:
+	case LLScriptFloaterManager::OBJ_GIVE_INVENTORY:
 		mChiclet = getChild<LLInvOfferChiclet>("inv_offer_chiclet");
 		break;
 	default:
@@ -530,8 +458,7 @@ void LLIMWellWindow::ObjectRowPanel::initChiclet(const LLUUID& object_id, bool n
 	}
 
 	mChiclet->setVisible(true);
-	mChiclet->setSessionId(object_id);
-//	mChiclet->setShowNewMessagesIcon(new_message);
+	mChiclet->setSessionId(notification_id);
 }
 
 //---------------------------------------------------------------------------------
@@ -780,10 +707,10 @@ void LLIMWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID
 	}
 }
 
-LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& object_id)
+LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id)
 {
 	LLChiclet* res = NULL;
-	ObjectRowPanel* panel = mMessageList->getTypedItemByValue<ObjectRowPanel>(object_id);
+	ObjectRowPanel* panel = mMessageList->getTypedItemByValue<ObjectRowPanel>(notification_id);
 	if (panel != NULL)
 	{
 		res = panel->mChiclet;
@@ -861,33 +788,33 @@ void LLIMWellWindow::delIMRow(const LLUUID& sessionId)
 	}
 }
 
-void LLIMWellWindow::addObjectRow(const LLUUID& object_id, bool new_message/* = false*/)
+void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_message/* = false*/)
 {
-	if (mMessageList->getItemByValue(object_id) == NULL)
+	if (mMessageList->getItemByValue(notification_id) == NULL)
 	{
-		ObjectRowPanel* item = new ObjectRowPanel(object_id, new_message);
-		if (mMessageList->insertItemAfter(mSeparator, item, object_id))
+		ObjectRowPanel* item = new ObjectRowPanel(notification_id, new_message);
+		if (mMessageList->insertItemAfter(mSeparator, item, notification_id))
 		{
 			handleItemAdded(IT_INSTANT_MESSAGE);
 		}
 		else
 		{
-			llwarns << "Unable to add Object Row into the list, objectID: " << object_id << llendl;
+			llwarns << "Unable to add Object Row into the list, notificationID: " << notification_id << llendl;
 			item->die();
 		}
 		reshapeWindow();
 	}
 }
 
-void LLIMWellWindow::removeObjectRow(const LLUUID& object_id)
+void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id)
 {
-	if (mMessageList->removeItemByValue(object_id))
+	if (mMessageList->removeItemByValue(notification_id))
 	{
 		handleItemRemoved(IT_INSTANT_MESSAGE);
 	}
 	else
 	{
-		llwarns << "Unable to remove Object Row from the list, objectID: " << object_id << llendl;
+		llwarns << "Unable to remove Object Row from the list, notificationID: " << notification_id << llendl;
 	}
 
 	reshapeWindow();
@@ -967,8 +894,7 @@ void LLIMWellWindow::closeAllImpl()
 		ObjectRowPanel* obj_panel = dynamic_cast <ObjectRowPanel*> (panel);
 		if (obj_panel)
 		{
-			LLScriptFloaterManager::instance()
-				.removeNotificationByObjectId(*iter);
+			LLScriptFloaterManager::instance().onRemoveNotification(*iter);
 		}
 	}
 }
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 0c81d1f369b..3790aa3ea9d 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -188,8 +188,8 @@ class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass<
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
 
-	void addObjectRow(const LLUUID& object_id, bool new_message = false);
-	void removeObjectRow(const LLUUID& object_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);
@@ -201,7 +201,7 @@ class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass<
 
 private:
 	LLChiclet * findIMChiclet(const LLUUID& sessionId);
-	LLChiclet* findObjectChiclet(const LLUUID& object_id);
+	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);
@@ -235,17 +235,8 @@ class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass<
 
 	class ObjectRowPanel: public LLPanel
 	{
-		typedef enum e_object_type
-		{
-			OBJ_UNKNOWN,
-
-			OBJ_SCRIPT,
-			OBJ_GIVE_INVENTORY,
-			OBJ_LOAD_URL
-		}EObjectType;
-
 	public:
-		ObjectRowPanel(const LLUUID& object_id, bool new_message = false);
+		ObjectRowPanel(const LLUUID& notification_id, bool new_message = false);
 		virtual ~ObjectRowPanel();
 		/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
 		/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
@@ -254,12 +245,8 @@ class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass<
 
 	private:
 		void onClosePanel();
-		static EObjectType getObjectType(const LLNotificationPtr& notification);
-		void initChiclet(const LLUUID& object_id, bool new_message = false);
-		std::string getObjectName(const LLUUID& object_id);
+		void initChiclet(const LLUUID& notification_id, bool new_message = false);
 
-		typedef std::map<std::string, EObjectType> object_type_map;
-		static object_type_map initObjectTypeMap();
 	public:
 		LLIMChiclet* mChiclet;
 	private:
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index c5d3d7cb25e..42f7793b5ad 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1263,10 +1263,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 		gInventory.addObserver(opener);
 	}
 
-	// Remove script dialog because there is no need in it no more.
-	LLUUID object_id = notification["payload"]["object_id"].asUUID();
-	LLScriptFloaterManager::instance().removeNotificationByObjectId(object_id);
-
 	delete this;
 	return false;
 }
@@ -1440,10 +1436,6 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 		gInventory.addObserver(opener);
 	}
 
-	// Remove script dialog because there is no need in it no more.
-	LLUUID object_id = notification["payload"]["object_id"].asUUID();
-	LLScriptFloaterManager::instance().removeNotificationByObjectId(object_id);
-
 	delete this;
 	return false;
 }
@@ -1594,7 +1586,6 @@ void inventory_offer_handler(LLOfferInfo* info)
 		{
 			payload["give_inventory_notification"] = TRUE;
 			LLNotificationPtr notification = LLNotifications::instance().add(p.payload(payload)); 
-			LLScriptFloaterManager::getInstance()->setNotificationToastId(object_id, notification->getID());
 		}
 	}
 }
diff --git a/indra/newview/skins/default/xui/en/panel_active_object_row.xml b/indra/newview/skins/default/xui/en/panel_active_object_row.xml
index 7657fb8055f..bef5f8dafd9 100644
--- a/indra/newview/skins/default/xui/en/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/en/panel_active_object_row.xml
@@ -10,10 +10,6 @@
   background_opaque="false"
   background_visible="true"
   bg_alpha_color="0.0 0.0 0.0 0.0" >
-  <string
-   name="unknown_obj">
-    Unknown Object
-  </string>
   <chiclet_script
     name="object_chiclet"
     layout="topleft"
-- 
GitLab