示例#1
0
//--------------------------------------------------------------------------
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))
//	{
//		LLNotifications::instance().cancel(notification);
//	}
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Modified: Catznip-2.5.0a
	// NOTE: this will be fired from LLScreenChannel::killToastByNotificationID() which treats visible and stored toasts differently
	if ( (notification) && (!notification->isCancelled()) && 
		 (LLNotificationManager::getInstance()->getHandlerForNotification(notification->getType()) == this)  )
	{
		LLScreenChannel* pChannel = dynamic_cast<LLScreenChannel*>(mChannel);
		LLToast* pToast = (pChannel) ? pChannel->getToastByNotificationID(notification->getID()) : NULL;
		if ( (!pToast) || (pToast->getCanBeStored()) )
		{
			LLNotifications::instance().cancel(notification);
		}
	}
// [/SL:KB]
}
示例#2
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);
}
	// removes all toasts from a channel
	virtual void		removeToastsFromChannel() 
	{
		for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
		{
			LLToast* toast = (*it);
			toast->setVisible(FALSE);
			toast->stopTimer();
			m_toast_pool.push_back(toast);

		}
		m_active_toasts.clear();
	};
示例#4
0
//--------------------------------------------------------------------------
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;

	LLToast* toast = (*it).toast;
	mStoredToastList.erase(it);
	mRejectToastSignal(toast->getNotificationID());
}
//--------------------------------------------------------------------------
void LLScreenChannel::killToastByNotificationID(LLUUID id)
{
	// searching among toasts on a screen
	std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
	
	if( it != mToastList.end())
	{
		LLToast* toast = it->getToast();
		// if it is a notification toast and notification is UnResponded - then respond on it
		// else - simply destroy a toast
		//
		// NOTE:	if a notification is unresponded this function will be called twice for the same toast.
		//			At first, the notification will be discarded, at second (it will be caused by discarding),
		//			the toast will be destroyed.
		if(toast && toast->isNotificationValid())
		{
			mRejectToastSignal(toast->getNotificationID());
		}
		else
		{

			deleteToast(toast);
			mToastList.erase(it);
			redrawToasts();
		}
		return;
	}

	// searching among stored toasts
	it = find(mStoredToastList.begin(), mStoredToastList.end(), id);

	if (it != mStoredToastList.end())
	{
		LLToast* toast = it->getToast();
		if (toast)
		{
			// send signal to a listener to let him perform some action on toast rejecting
			mRejectToastSignal(toast->getNotificationID());
			deleteToast(toast);
		}
	}

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

}
示例#6
0
//--------------------------------------------------------------------------
void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)
{
	std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
	
	if( it != mToastList.end() && panel)
	{
		LLToast* toast = (*it).toast;
		LLPanel* old_panel = toast->getPanel();
		toast->removeChild(old_panel);
		delete old_panel;
		toast->insertPanel(panel);
		toast->resetTimer();
		redrawToasts();
	}
}
//--------------------------------------------------------------------------
void LLScreenChannel::hideToastsFromScreen()
{
	for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++)
	{
		LLToast* toast = it->getToast();
		if (toast)
		{
			toast->setVisible(FALSE);
		}
		else
		{
			llwarns << "Attempt to hide a deleted toast." << llendl;
		}
	}
}
//--------------------------------------------------------------------------
void LLScreenChannel::hideToast(const LLUUID& notification_id)
{
	std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), notification_id);
	if(mToastList.end() != it)
	{
		LLToast* toast = it->getToast();
		if (toast)
		{
			toast->hide();
		}
		else
		{
			llwarns << "Attempt to hide a deleted toast." << llendl;
		}
	}
}
void LLScreenChannel::closeHiddenToasts(const Matcher& matcher)
{
	// since we can't guarantee that close toast operation doesn't change mToastList
	// we collect matched toasts that should be closed into separate list
	std::list<LLToast*> toasts;
	for (std::vector<ToastElem>::iterator it = mToastList.begin(); it
			!= mToastList.end(); it++)
	{
		LLToast* toast = it->getToast();
		// add to list valid toast that match to provided matcher criteria
		if (toast != NULL && !toast->isDead() && toast->getNotification() != NULL
				&& !toast->getVisible() && matcher.matches(toast->getNotification()))
		{
			toasts.push_back(toast);
		}
	}

	// close collected toasts
	for (std::list<LLToast*>::iterator it = toasts.begin(); it
			!= toasts.end(); it++)
	{
		LLToast* toast = *it;
		toast->closeFloater();
	}
}
void LLNearbyChatScreenChannel::updateSize(LLRect old_world_rect, LLRect new_world_rect)
{
	for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
	{
		LLToast* toast = it->get();

		if (toast)
		{
			LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel());

			if(panel)
			{
				reshapePanel(panel);
				toast->reshapeToPanel();
			}
		}
	}
	arrangeToasts();
}
void LLNearbyChatScreenChannel::showToastsBottom()
{
	if(mStopProcessing)
		return;

	LLRect	toast_rect;	
	updateBottom();
	S32 channel_bottom = getRect().mBottom;

	S32		bottom = channel_bottom;
	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 > gFloaterView->getRect().getHeight())
		{
			while(it!=m_active_toasts.end())
			{
				addToToastPool(it->get());
				it=m_active_toasts.erase(it);
			}
			break;
		}

		toast_rect = toast->getRect();
		toast_rect.setLeftTopAndSize(getRect().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);
		}
	}

	}
示例#12
0
bool	LLNearbyChatScreenChannel::createPoolToast()
{
	LLToastPanelBase* 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));

	LL_DEBUGS("NearbyChat") << "Creating and pooling toast" << llendl;	
	m_toast_pool.push_back(toast->getHandle());
	return true;
}
bool	LLNearbyChatScreenChannel::createPoolToast()
{
	LLToastPanelBase* 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 LLToast(p); 
	
	
	toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1));
	toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1));
	
	m_toast_pool.push_back(toast);
	return true;
}
示例#14
0
//--------------------------------------------------------------------------
void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id)
{
	std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id);

	if( it == mStoredToastList.end() )
		return;

	LLToast* toast = (*it).toast;

	if(toast->getVisible())
	{
		// toast is already in channel
		return;
	}

	toast->setIsHidden(false);
	toast->resetTimer();
	mToastList.push_back((*it));

	redrawToasts();
}
//--------------------------------------------------------------------------
void LLScreenChannel::removeAndStoreAllStorableToasts()
{
	if(mToastList.size() == 0)
		return;

	hideToastsFromScreen();
	for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end();)
	{
		LLToast* toast = it->getToast();
		if(toast && toast->getCanBeStored())
		{
			storeToast(*it);
			it = mToastList.erase(it);
		}
		else
		{
			++it;
		}
	}
	redrawToasts();
}
//--------------------------------------------------------------------------
void LLScreenChannel::loadStoredToastsToChannel()
{
	std::vector<ToastElem>::iterator it;

	if(mStoredToastList.size() == 0)
		return;

	for(it = mStoredToastList.begin(); it != mStoredToastList.end(); ++it)
	{
		LLToast* toast = it->getToast();
		if (toast)
		{
			toast->setIsHidden(false);
			toast->startTimer();
			mToastList.push_back(*it);
		}
	}

	mStoredToastList.clear();
	redrawToasts();
}
//--------------------------------------------------------------------------
void LLScreenChannel::removeToastsBySessionID(LLUUID id)
{
	if(mToastList.size() == 0)
		return;

	hideToastsFromScreen();
	for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end();)
	{
		LLToast* toast = it->getToast();
		if(toast && toast->getSessionID() == id)
		{
			deleteToast(toast);
			it = mToastList.erase(it);
		}
		else
		{
			++it;
		}
	}
	redrawToasts();
}
//--------------------------------------------------------------------------
void LLScreenChannel::showToastsCentre()
{
	LLToast* toast = mToastList[0].getToast();
	if (!toast)
	{
		llwarns << "Attempt to display a deleted toast." << llendl;
		return;
	}

	LLRect	toast_rect;
	S32		bottom = (getRect().mTop - getRect().mBottom)/2 + toast->getRect().getHeight()/2;
	std::vector<ToastElem>::reverse_iterator it;

	for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
	{
		LLToast* toast = it->getToast();
		if (!toast)
		{
			llwarns << "Attempt to display a deleted toast." << llendl;
			return;
		}

		toast_rect = toast->getRect();
		toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + gSavedSettings.getS32("ToastGap"), toast_rect.getWidth() ,toast_rect.getHeight());
		toast->setRect(toast_rect);

		toast->setVisible(TRUE);
	}
}
bool	LLNearbyChatScreenChannel::createPoolToast()
{
	LLToastPanelBase* 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);
	reshapePanel(panel);
	
	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 LLScreenChannel::addToast(const LLToast::Params& p)
{
	bool store_toast = false, show_toast = false;

	mDisplayToastsAlways ? show_toast = true : show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
	store_toast = !show_toast && p.can_be_stored && mCanStoreToasts;

	if(!show_toast && !store_toast)
	{
		mRejectToastSignal(p.notif_id);
		return;
	}

	LLToast* toast = new LLToast(p);
	ToastElem new_toast_elem(toast->getHandle());

	toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, _1));
	toast->setOnToastDestroyedCallback(boost::bind(&LLScreenChannel::onToastDestroyed, this, _1));
	if(mControlHovering)
	{
		toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));
		toast->setMouseEnterCallback(boost::bind(&LLScreenChannel::stopToastTimer, this, toast));
		toast->setMouseLeaveCallback(boost::bind(&LLScreenChannel::startToastTimer, this, toast));
	}
	
	if(show_toast)
	{
		mToastList.push_back(new_toast_elem);
		if(p.can_be_stored)
		{
			// store toasts immediately - EXT-3762
			storeToast(new_toast_elem);
		}
		updateShowToastsState();
		redrawToasts();
	}	
	else // store_toast
	{
		mHiddenToastsNum++;
		storeToast(new_toast_elem);
	}
}
void LLNearbyChatScreenChannel::showToastsBottom()
{
	if(mStopProcessing)
		return;

	LLRect	toast_rect;	
	S32		bottom = getRect().mBottom;
	S32		margin = gSavedSettings.getS32("ToastGap");

	for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
	{
		LLToast* toast = (*it);
		S32 toast_top = bottom + toast->getRect().getHeight() + margin;

		if(toast_top > gFloaterView->getRect().getHeight())
		{
			while(it!=m_active_toasts.end())
			{
				toast->setVisible(FALSE);
				toast->stopTimer();
				m_toast_pool.push_back(toast);
				it=m_active_toasts.erase(it);
			}
			break;
		}
		bottom = toast_top - toast->getTopPad();
	}

	// use reverse order to provide correct z-order and avoid toast blinking
	for(std::vector<LLToast*>::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it)
	{
		LLToast* toast = (*it);
		S32 toast_top = bottom + toast->getTopPad();

		toast_rect = toast->getRect();
		toast_rect.setLeftTopAndSize(getRect().mLeft , toast_top, toast_rect.getWidth() ,toast_rect.getHeight());

		toast->setRect(toast_rect);
		toast->setIsHidden(false);
		toast->setVisible(TRUE);

		bottom = toast->getRect().mBottom - margin;
	}
}
void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
{
	//look in pool. if there is any message
	if(mStopProcessing)
		return;

	/*
    find last toast and check ID
	*/

	if(m_active_toasts.size())
	{
		LLUUID fromID = notification["from_id"].asUUID();		// agent id or object id
		std::string from = notification["from"].asString();
		LLToast* toast = m_active_toasts[0];
		LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel());

		if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText())
		{
			panel->addMessage(notification);
			toast->reshapeToPanel();
			toast->resetTimer();
	
			arrangeToasts();
			return;
		}
	}
	

	
	if(m_toast_pool.empty())
	{
		//"pool" is empty - create one more panel
		if(!createPoolToast())//created toast will go to pool. so next call will find it
			return;
		addNotification(notification);
		return;
	}

	int chat_type = notification["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

	LLToast* toast = m_toast_pool.back();

	m_toast_pool.pop_back();


	LLToastPanelBase* panel = dynamic_cast<LLToastPanelBase*>(toast->getPanel());
	if(!panel)
		return;
	panel->init(notification);

	toast->reshapeToPanel();
	toast->resetTimer();
	
	m_active_toasts.insert(m_active_toasts.begin(),toast);

	arrangeToasts();
}
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;

	// <FS:Ansariel> Configurable nearby chat toasts offset
	//S32		bottom = channel_bottom + 80;
	S32		bottom = channel_bottom + gSavedSettings.getS32("FSNearbyChatToastsOffset");
	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);
		}
	}

}
//--------------------------------------------------------------------------
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;
}
//--------------------------------------------------------------------------
void LLScreenChannel::showToastsTop()
{
	LLRect channel_rect = getChannelRect();

	LLRect	toast_rect;	
	S32		top = channel_rect.mTop;
	std::vector<ToastElem>::reverse_iterator it;

	updateRect();

	LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get());

	// <FS:Ansariel> Show toasts in front of other floaters
	BOOL toasts_in_front = gSavedSettings.getBOOL("FSShowToastsInFront");

	// Use a local variable instead of mToastList.
	// mToastList can be modified during recursive calls and then all iteratos will be invalidated.
	std::vector<ToastElem> vToastList( mToastList );

	for(it = vToastList.rbegin(); it != vToastList.rend(); ++it)
	{
		if(it != vToastList.rbegin())
		{
			LLToast* toast = (it-1)->getToast();
			if (!toast)
			{
				llwarns << "Attempt to display a deleted toast." << llendl;
				return;
			}

			top = toast->getRect().mBottom - toast->getTopPad();
			gSavedSettings.getS32("ToastGap");
		}

		LLToast* toast = it->getToast();
		if (!toast)
		{
			llwarns << "Attempt to display a deleted toast." << llendl;
			return;
		}

		toast_rect = toast->getRect();
		toast_rect.setLeftTopAndSize(channel_rect.mRight - toast_rect.getWidth(),
			top, toast_rect.getWidth(),
			toast_rect.getHeight());
		toast->setRect(toast_rect);

		if(floater && floater->overlapsScreenChannel())
		{
			if(it == vToastList.rbegin())
			{
				// move first toast above docked floater
				S32 shift = -floater->getRect().getHeight();
				if(floater->getDockControl())
				{
					shift -= floater->getDockControl()->getTongueHeight();
				}
				toast->translate(0, shift);
			}

			LLRect channel_rect = getChannelRect();
			// don't show toasts if there is not enough space
			if(toast_rect.mBottom < channel_rect.mBottom)
			{
				break;
			}
		}

		bool stop_showing_toasts = toast->getRect().mBottom < channel_rect.mBottom;

		if(!stop_showing_toasts)
		{
			if( it != vToastList.rend()-1)
			{
				S32 toast_bottom = toast->getRect().mBottom - gSavedSettings.getS32("ToastGap");
				stop_showing_toasts = toast_bottom < channel_rect.mBottom;
			}
		} 

		// at least one toast should be visible
		if(it == vToastList.rbegin())
		{
			stop_showing_toasts = false;
		}

		if(stop_showing_toasts)
			break;

		if (!toast->getVisible())
		{
			// HACK
			// EXT-2653: it is necessary to prevent overlapping for secondary showed toasts
			toast->setVisible(TRUE);
		}		
		// <FS:Ansariel> Show toasts in front of other floaters
		//if (!toast->hasFocus())
		if (!toast->hasFocus() && !toasts_in_front)
		// </FS:Ansariel> Show toasts in front of other floaters
		{
			// Fixing Z-order of toasts (EXT-4862)
			// Next toast will be positioned under this one.
			gFloaterView->sendChildToBack(toast);
		}
	}

	// Dismiss toasts we don't have space for (STORM-391).
	std::vector<LLToast*> toasts_to_hide;

	if(it != vToastList.rend())
	{
		mHiddenToastsNum = 0;

		for(; it != vToastList.rend(); it++)
		{
			LLToast* toast = it->getToast();
			if (toast)
			{
				toasts_to_hide.push_back(toast);
			}
		}
	}

	for (std::vector<LLToast*>::iterator it = toasts_to_hide.begin(), end_it = toasts_to_hide.end();
		it != end_it;
		++it)
	{
		(*it)->hide();
	}
}
示例#26
0
//--------------------------------------------------------------------------
void LLScreenChannel::showToastsBottom()
{
	LLRect	toast_rect;	
	S32		bottom = getRect().mBottom - gFloaterView->getRect().mBottom;
	S32		toast_margin = 0;
	std::vector<ToastElem>::reverse_iterator it;

	LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get());

	for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
	{
		if(it != mToastList.rbegin())
		{
			LLToast* toast = (*(it-1)).toast;
			bottom = toast->getRect().mTop - toast->getTopPad();
			toast_margin = gSavedSettings.getS32("ToastGap");
		}

		toast_rect = (*it).toast->getRect();
		toast_rect.setOriginAndSize(getRect().mRight - toast_rect.getWidth(),
				bottom + toast_margin, toast_rect.getWidth(),
				toast_rect.getHeight());
		(*it).toast->setRect(toast_rect);

		if(floater && floater->overlapsScreenChannel())
		{
			if(it == mToastList.rbegin())
			{
				// move first toast above docked floater
				S32 shift = floater->getRect().getHeight();
				if(floater->getDockControl())
				{
					shift += floater->getDockControl()->getTongueHeight();
				}
				(*it).toast->translate(0, shift);
			}

			LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
			// don't show toasts if there is not enough space
			if(toast_rect.mTop > world_rect.mTop)
			{
				break;
			}
		}

		bool stop_showing_toasts = (*it).toast->getRect().mTop > getRect().mTop;

		if(!stop_showing_toasts)
		{
			if( it != mToastList.rend()-1)
			{
				S32 toast_top = (*it).toast->getRect().mTop + gSavedSettings.getS32("ToastGap");
				stop_showing_toasts = toast_top > getRect().mTop;
			}
		} 

		// at least one toast should be visible
		if(it == mToastList.rbegin())
		{
			stop_showing_toasts = false;
		}

		if(stop_showing_toasts)
			break;

		if( !(*it).toast->getVisible() )
		{
			// HACK
			// EXT-2653: it is necessary to prevent overlapping for secondary showed toasts
			(*it).toast->setVisible(TRUE);
		}		
		if(!(*it).toast->hasFocus())
		{
			// Fixing Z-order of toasts (EXT-4862)
			// Next toast will be positioned under this one.
			gFloaterView->sendChildToBack((*it).toast);
		}
	}

	if(it != mToastList.rend())
	{
		mHiddenToastsNum = 0;
		for(; it != mToastList.rend(); it++)
		{
			(*it).toast->stopTimer();
			(*it).toast->setVisible(FALSE);
			mHiddenToastsNum++;
		}
	}
	else
	{
		closeOverflowToastPanel();
	}
}