//--------------------------------------------------------------------------
bool LLAlertHandler::processNotification(const LLNotificationPtr& notification)
{
	if(mChannel.isDead())
	{
		return false;
	}

	// arrange a channel on a screen
	if(!mChannel.get()->getVisible())
	{
		initChannel();
	}

	if (notification->canLogToIM() && notification->hasFormElements())
	{
		const std::string name = LLHandlerUtil::getSubstitutionName(notification);

		LLUUID from_id = notification->getPayload()["from_id"];

// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9)
		// Don't spawn an IM session for non-chat related events:
		//   - LLHandlerUtil::logToIMP2P() below will still be called with to_file_only == false
		//   - LLHandlerUtil::logToIM() will eventually be called as a result and without an open IM session it will log the
		//     same message as it would for an open session whereas to_file_only == true would take a different code path
		if ( (RlvActions::hasOpenP2PSession(from_id)) || (RlvActions::canStartIM(from_id)) )
		{
// [/RLVa:KB]
			// firstly create session...
			LLHandlerUtil::spawnIMSession(name, from_id);
// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9)
		}
// [/RLVa:KB]

		// ...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;
}
예제 #2
0
//--------------------------------------------------------------------------
bool LLIMHandler::processNotification(const LLSD& notify)
{
	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());
	}
	return true;
}
예제 #3
0
//--------------------------------------------------------------------------
LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id)
{
	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));
}
//--------------------------------------------------------------------------
LLTipHandler::LLTipHandler(e_notification_type type, const LLSD& id)
{
	mType = type;	

	// Getting a Channel for our notifications
	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
	if(channel)
	{
		channel->setOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1));
		mChannel = channel->getHandle();
	}
}
void LLScriptFloater::hideToastsIfNeeded()
{
	using namespace LLNotificationsUI;

	// find channel
	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->findChannelByID(
		LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
	// update notification channel state
	if(channel)
	{
		channel->updateShowToastsState();
		channel->redrawToasts();
	}
}
예제 #6
0
// virtual
void LLInspectToast::onOpen(const LLSD& notification_id)
{
	LLInspect::onOpen(notification_id);
	LLToast* toast = mScreenChannel->getToastByNotificationID(notification_id);
	if (toast == NULL)
	{
		llwarns << "Could not get requested toast  from screen channel." << llendl;
		return;
	}
	mConnection = toast->setOnToastDestroyedCallback(boost::bind(&LLInspectToast::onToastDestroy, this, _1));

	LLPanel * panel = toast->getPanel();
	panel->setVisible(TRUE);
	panel->setMouseOpaque(FALSE);
	if(mPanel != NULL && mPanel->getParent() == this)
	{
		removeChild(mPanel);
	}
	addChild(panel);
	panel->setFocus(TRUE);
	mPanel = panel;


	LLRect panel_rect;
	panel_rect = panel->getRect();
	reshape(panel_rect.getWidth(), panel_rect.getHeight());

	LLUI::positionViewNearMouse(this);
}
void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif)
{
	LLScreenChannel* channel = dynamic_cast<LLScreenChannel *>(mChannel);
	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)));
		}
	}
}
예제 #8
0
//--------------------------------------------------------------------------
LLOfferHandler::LLOfferHandler(e_notification_type type, const LLSD& id)
{
	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));

	// <FS:ND> Register with observer so we notice when mChannel diees
	if( mChannel )
		mChannel->setObserver( this );
	// </FS:ND>
}
예제 #9
0
//--------------------------------------------------------------------------
bool LLGroupHandler::processNotification(const LLSD& notify)
{
	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);

		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);

		// send a signal to the counter manager
		mNewNotificationSignal();

		LLGroupActions::refresh_notices();
	}
	else if (notify["sigtype"].asString() == "delete")
	{
		mChannel->killToastByNotificationID(notification->getID());
	}
	return false;
}
//--------------------------------------------------------------------------
bool LLScriptHandler::processNotification(const LLSD& notify)
{
	if(mChannel.isDead())
	{
		return false;
	}

	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());

	if(!notification)
		return false;

	// arrange a channel on a screen
	if(!mChannel.get()->getVisible())
	{
		initChannel();
	}
	
	if(notify["sigtype"].asString() == "add")
	{
		if (LLHandlerUtil::canLogToIM(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
		{
			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);
			}

			// send a signal to the counter manager
			mNewNotificationSignal();
		}
	}
	else if (notify["sigtype"].asString() == "delete")
	{
		if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
		{
			LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
		}
		else
		{
			mChannel.get()->killToastByNotificationID(notification->getID());
		}
	}
	return false;
}
예제 #11
0
//--------------------------------------------------------------------------
bool LLAlertHandler::processNotification(const LLSD& notify)
{
	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 (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());
	}
	return false;
}
예제 #12
0
//--------------------------------------------------------------------------
bool LLIMHandler::processNotification(const LLSD& notify)
{
	if(mChannel.isDead())
	{
		return false;
	}

	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());

	if(!notification)
		return false;

	static LLCachedControl<bool> fsUseNearbyChatConsole(gSavedSettings, "FSUseNearbyChatConsole");
	if (FSLogImToChatConsole && fsUseNearbyChatConsole)
	{
		if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
		{
			LLSD substitutions = notification->getSubstitutions();

			// FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name
			std::string group;
			LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(substitutions["SESSION_ID"]);
			if(session)
			{
				S32 groupNameLength = gSavedSettings.getS32("FSShowGroupNameLength");
				if(groupNameLength != 0 && session->isGroupSessionType())
				{
					group = session->mName.substr(0,groupNameLength);
				}
			}
			// FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name

			// Filter notifications with empty ID and empty message
			if (substitutions["FROM_ID"].asString() == "" && substitutions["MESSAGE"].asString() == "") return false;

			// Ansarial, replace long lock of local DN handling with the following call
			//LLAvatarNameCache::get(LLUUID(substitutions["FROM_ID"].asString()), boost::bind(&LLIMHandler::onAvatarNameLookup, this, _1, _2, substitutions["MESSAGE"].asString()));
			LLAvatarNameCache::get(LLUUID(substitutions["FROM_ID"].asString()), boost::bind(&LLIMHandler::onAvatarNameLookup, this, _1, _2, substitutions["MESSAGE"].asString(),group)); // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name
		}
	}
	else
	{
		// arrange a channel on a screen
		if(!mChannel.get()->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.get());
			if(channel)
				channel->addToast(p);

			// send a signal to the counter manager;
			mNewNotificationSignal();
		}
		else if (notify["sigtype"].asString() == "delete")
		{
			mChannel.get()->killToastByNotificationID(notification->getID());
		}
	}
	return false;
}
//--------------------------------------------------------------------------
bool LLTipHandler::processNotification(const LLSD& notify)
{
	if(mChannel.isDead())
	{
		return false;
	}

	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());

	if(!notification)
		return false;	

	// arrange a channel on a screen
	if(!mChannel.get()->getVisible())
	{
		initChannel();
	}

	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
	{
		// archive message in nearby chat
		if (LLHandlerUtil::canLogToNearbyChat(notification))
		{
			LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);

			// don't show toast if Nearby Chat is opened
			LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance();
			// <FS:Zi> Remove floating chat bar
			// LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
			// if (!nearby_chat_bar->isMinimized() && nearby_chat_bar->getVisible() && nearby_chat->getVisible())
			if (nearby_chat->getVisible())
			// </FS:Zi>
			{
				return false;
			}
		}

		std::string session_name = notification->getPayload()["SESSION_NAME"];
		const std::string name = notification->getSubstitutions()["NAME"];
		const LLUUID agent_id = notification->getSubstitutions()["AGENT-ID"];
		
		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);
// [SL:KB] - Patch: Chat-Logs | Checked: 2010-11-18 (Catznip-2.4.0c) | Added: Catznip-2.4.0c
			LLHandlerUtil::logToIMP2P(notification, false);
// [/SL:KB]
		}

		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))
		{
			return false;
		}

		// [FIRE-3522 : SJ] Only show Online/Offline toast when ChatOnlineNotification is enabled or the Friend is one you want to have on/offline notices from
		if (!gSavedSettings.getBOOL("ChatOnlineNotification") && ("FriendOffline" == notification->getName() || "FriendOnline" == notification->getName()))
		{
			// [FIRE-3522 : SJ] Only show Online/Offline toast for groups which have enabled "Show notice for this set" and in the settingpage of CS is checked that the messages need to be in Toasts
			if (!(gSavedSettings.getBOOL("FSContactSetsNotificationToast") && LGGContactSets::getInstance()->notifyForFriend(agent_id)))
			{
				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);

		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
		if(channel)
			channel->addToast(p);
	}
	else if (notify["sigtype"].asString() == "delete")
	{
		mChannel.get()->killToastByNotificationID(notification->getID());
	}
	return false;
}
//--------------------------------------------------------------------------
bool LLScriptHandler::processNotification(const LLSD& notify)
{
	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")
	{
		// Don't log persisted notifications a second time
		if (!notification->isPersisted())
		{
			// Archive message in nearby chat if desired
			if (LLHandlerUtil::canLogToNearbyChat(notification))
			{
				LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
			}
			// Archive message in instant message if desired
			if (LLHandlerUtil::canLogToIM(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();
		}
	}
	else if (notify["sigtype"].asString() == "delete")
	{
		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());
		}
	}
	return false;
}
//--------------------------------------------------------------------------
bool LLOfferHandler::processNotification(const LLSD& notify)
{
	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")
	{


		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(LLHandlerUtil::isNotificationReusable(notification));

			LLUUID session_id;
//			if (LLHandlerUtil::canSpawnIMSession(notification))
// [RLVa:KB] - Checked: 2010-04-20 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
			// Don't spawn a new IM session for inventory offers if this notification was subject to @shownames=n
			// RELEASE-RLVa: [SL-2.3.0] Test on every new release to make sure the notification gets routed the way we want it to be
			bool fSpawnIM = (LLHandlerUtil::canSpawnIMSession(notification)) && (!notification->getPayload().has("rlv_shownames"));
			if (fSpawnIM)
// [/RLVa:KB]
			{
				const std::string name = LLHandlerUtil::getSubstitutionName(notification);

				LLUUID from_id = notification->getPayload()["from_id"];

				session_id = LLHandlerUtil::spawnIMSession(name, from_id);
			}

			bool show_toast = LLHandlerUtil::canSpawnToast(notification);
//			bool add_notid_to_im = LLHandlerUtil::canAddNotifPanelToIM(notification);
// [RLVa:KB] - Checked: 2010-04-20 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
			// NOTE: add_notid_to_im needs to be FALSE if we suppressed spawning an IM because in that case the notification needs to
			//       be routed to the "syswell" or the inventory offer floater will dissapear and the user won't be able to accept it
			bool add_notid_to_im = (fSpawnIM) && (LLHandlerUtil::canAddNotifPanelToIM(notification));
// [/RLVa:KB]
			if (add_notid_to_im)
			{
				LLHandlerUtil::addNotifPanelToIM(notification);
			}

			if (notification->getPayload().has("SUPPRESS_TOAST")
						&& notification->getPayload()["SUPPRESS_TOAST"])
			{
				LLNotificationsUtil::cancel(notification);
			}
			else if(show_toast)
			{
				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();
				}
			}

			if (LLHandlerUtil::canLogToIM(notification))
			{
				// log only to file if notif panel can be embedded to IM and IM is opened
// [RLVa:KB] - Checked: 2010-04-20 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
				if (notification->getPayload().has("rlv_shownames"))
				{
					// Log to chat history if this notification was subject to @shownames=n
					LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
				}
				else if (add_notid_to_im && LLHandlerUtil::isIMFloaterOpened(notification))
// [/RLVa:KB]
//				if (add_notid_to_im && LLHandlerUtil::isIMFloaterOpened(notification))
				{
					LLHandlerUtil::logToIMP2P(notification, true);
				}
				else
				{
					LLHandlerUtil::logToIMP2P(notification);
				}
			}
		}
	}
	else if (notify["sigtype"].asString() == "delete")
	{
		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 (LLHandlerUtil::canAddNotifPanelToIM(notification)
//					&& !LLHandlerUtil::isIMFloaterOpened(notification))
// [SL:KB] - Checked: 2010-04-20 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
			// Repro:
			//   1) have someone drop you 2 inventory items (new IM session will be spawned)
			//   2) accept/decline the inventory offers as they come in
			//		-> unread IM counter shows 0
			//   3) toggle "Enable plain text chat history" while the IM session with the inventory offers isn't the active session
			//		-> unread IM counter shows -2
			//		-> LLHandlerUtil::decIMMesageCounter() really should be fixed to check for "0" before decreasing the count but
			//         there are enough bugfixes in RLVa as it is already :(
			// Fix:
			//   - the one and only time we need to decrease the unread IM count is when we've clicked any of the buttons on the *toast*
			//   - since LLIMFloater::updateMessages() hides the toast when we open the IM (which resets the unread count to 0) we should 
			//     *only* decrease the unread IM count if there's a visible toast since the unread count will be at 0 otherwise anyway
			LLScreenChannel* pChannel = dynamic_cast<LLScreenChannel*>(mChannel);
			LLToast* pToast = (pChannel) ? pChannel->getToastByNotificationID(notification->getID()) : NULL;
			if ( (pToast) && (!pToast->getCanBeStored()) )
// [/SL:KB]
			{
				LLHandlerUtil::decIMMesageCounter(notification);
			}
			mChannel->killToastByNotificationID(notification->getID());
		}
	}

	return false;
}
//--------------------------------------------------------------------------
bool LLOfferHandler::processNotification(const LLSD& notify)
{
	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")
	{


		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(LLHandlerUtil::isNotificationReusable(notification));

			LLUUID session_id;
			if (LLHandlerUtil::canSpawnIMSession(notification))
			{
				const std::string name = LLHandlerUtil::getSubstitutionName(notification);

				LLUUID from_id = notification->getPayload()["from_id"];

				session_id = LLHandlerUtil::spawnIMSession(name, from_id);
			}

			bool show_toast = LLHandlerUtil::canSpawnToast(notification);
			bool add_notid_to_im = LLHandlerUtil::canAddNotifPanelToIM(notification);
			if (add_notid_to_im)
			{
				LLHandlerUtil::addNotifPanelToIM(notification);
			}

			if (notification->getPayload().has("SUPPRESS_TOAST")
						&& notification->getPayload()["SUPPRESS_TOAST"])
			{
				LLNotificationsUtil::cancel(notification);
			}
			else if(show_toast)
			{
				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();
				}
			}
			
			if (LLHandlerUtil::canLogToNearbyChat(notification))
			{
				LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
			}

			if (LLHandlerUtil::canLogToIM(notification))
			{
				// 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);
				}
			}
		}
	}
	else if (notify["sigtype"].asString() == "delete")
	{
		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 (LLHandlerUtil::canAddNotifPanelToIM(notification)
					&& !LLHandlerUtil::isIMFloaterOpened(notification))
			{
				LLHandlerUtil::decIMMesageCounter(notification);
			}
			mChannel->killToastByNotificationID(notification->getID());
		}
	}

	return false;
}
//--------------------------------------------------------------------------
bool LLTipHandler::processNotification(const LLSD& notify)
{
	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 (LLHandlerUtil::canLogToNearbyChat(notification))
		{
			LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);

			// don't show toast if Nearby Chat is opened
			LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<
					LLNearbyChat>("nearby_chat", LLSD());
			if (nearby_chat->getVisible())
			{
				return true;
			}
		}

		const std::string name = notification->getSubstitutions()["NAME"];
		LLUUID from_id = notification->getPayload()["from_id"];
		if (LLHandlerUtil::canLogToIM(notification))
		{
			LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, 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))
		{
			return true;
		}

		LLToastPanel* notify_box = NULL;
		if("FriendOffline" == notification->getName() || "FriendOnline" == notification->getName())
		{
			LLOnlineStatusToast::Params p;
			p.notification = notification;
			p.message = notification->getMessage();
			p.avatar_id = notification->getPayload()["FROM_ID"];
			notify_box = new LLOnlineStatusToast(p);
		}
		else
		{
			notify_box = new LLToastNotifyPanel(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);
	}
	else if (notify["sigtype"].asString() == "delete")
	{
		mChannel->killToastByNotificationID(notification->getID());
	}
	return true;
}
//--------------------------------------------------------------------------
bool LLTipHandler::processNotification(const LLSD& notify)
{
	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 (LLHandlerUtil::canLogToNearbyChat(notification))
		{
			LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);

			// don't show toast if Nearby Chat is opened
			LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<
					LLNearbyChat>("nearby_chat", LLSD());
			if (nearby_chat->getVisible())
			{
				return false;
			}
		}

		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);
// [SL:KB] - Patch: Chat-Logs | Checked: 2010-11-18 (Catznip-2.4.0c) | Added: Catznip-2.4.0c
			LLHandlerUtil::logToIMP2P(notification, false);
// [/SL:KB]
		}

		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))
		{
			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);

		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
		if(channel)
			channel->addToast(p);
	}
	else if (notify["sigtype"].asString() == "delete")
	{
		mChannel->killToastByNotificationID(notification->getID());
	}
	return false;
}