Пример #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]
}
// static
bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification)
{
	return notification->getType() == "notifytip"
			&&  FRIEND_ONLINE != notification->getName()
			&& FRIEND_OFFLINE != notification->getName()
			&& INVENTORY_ACCEPTED != notification->getName()
			&& INVENTORY_DECLINED != notification->getName();
}
Пример #3
0
//--------------------------------------------------------------------------
void LLGroupHandler::onRejectToast(LLUUID& id)
{
	LLNotificationPtr notification = LLNotifications::instance().find(id);

	if (notification && LLNotificationManager::getInstance()->getHandlerForNotification(notification->getType()) == this)
	{
		LLNotifications::instance().cancel(notification);
	}
}
LLSD LLNotificationsListener::asLLSD(LLNotificationPtr note)
{
    LLSD notificationInfo(note->asLLSD());
    // For some reason the following aren't included in LLNotification::asLLSD().
    notificationInfo["summary"] = note->summarize();
    notificationInfo["id"]      = note->id();
    notificationInfo["type"]    = note->getType();
    notificationInfo["message"] = note->getMessage();
    notificationInfo["label"]   = note->getLabel();
    return notificationInfo;
}
//--------------------------------------------------------------------------
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);
	}
}
Пример #6
0
//--------------------------------------------------------------------------
bool LLNotificationManager::onNotification(const LLSD& notify)
{
	LLSysHandler* handle = NULL;

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

	std::string notification_type = notification->getType();
	handle = static_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get());

	if(!handle)
		return false;
	
	// If we don't return false, everything that follows breaks.
	handle->processNotification(notify);
	return false;
}
Пример #7
0
LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect) : 
LLToastPanel(notification),
mTextBox(NULL),
mInfoPanel(NULL),
mControlPanel(NULL),
mNumOptions(0),
mNumButtons(0),
mAddedDefaultBtn(false),
mCloseNotificationOnDestroy(true)
{
	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_notification.xml");
	if(rect != LLRect::null)
	{
		this->setShape(rect);
	}		 
	mInfoPanel = getChild<LLPanel>("info_panel");
	mControlPanel = getChild<LLPanel>("control_panel");
	BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
	// customize panel's attributes
	// is it intended for displaying a tip
	mIsTip = notification->getType() == "notifytip";
	// is it a script dialog
	mIsScriptDialog = (notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup");
	// is it a caution
	//
	// caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
	// notify xml template specifies that it is a caution
	// tip-style notification handle 'caution' differently -they display the tip in a different color
	mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;

	// setup parameters
	// get a notification message
	mMessage = notification->getMessage();
	// init font variables
	if (!sFont)
	{
		sFont = LLFontGL::getFontSansSerif();
		sFontSmall = LLFontGL::getFontSansSerifSmall();
	}
	// clicking on a button does not steal current focus
	setIsChrome(TRUE);
	// initialize
	setFocusRoot(!mIsTip);
	// get a form for the notification
	LLNotificationFormPtr form(notification->getForm());
	// get number of elements
	mNumOptions = form->getNumElements();

	// customize panel's outfit
	// preliminary adjust panel's layout
	//move to the end 
	//mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form);

	// adjust text options according to the notification type
	// add a caution textbox at the top of a caution notification
	if (mIsCaution && !mIsTip)
	{
		mTextBox = getChild<LLTextBox>("caution_text_box");
	}
	else
	{
		mTextBox = getChild<LLTextEditor>("text_editor_box"); 
	}

	// *TODO: magic numbers(???) - copied from llnotify.cpp(250)
	const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; 

	mTextBox->setMaxTextLength(MAX_LENGTH);
	mTextBox->setVisible(TRUE);
	mTextBox->setValue(notification->getMessage());

	// add buttons for a script notification
	if (mIsTip)
	{
		adjustPanelForTipNotice();
	}
	else
	{
		std::vector<index_button_pair_t> buttons;
		buttons.reserve(mNumOptions);
		S32 buttons_width = 0;
		// create all buttons and accumulate they total width to reshape mControlPanel
		for (S32 i = 0; i < mNumOptions; i++)
		{
			LLSD form_element = form->getElement(i);
			if (form_element["type"].asString() != "button")
			{
				continue;
			}
			LLButton* new_button = createButton(form_element, TRUE);
			buttons_width += new_button->getRect().getWidth();
			S32 index = form_element["index"].asInteger();
			buttons.push_back(index_button_pair_t(index,new_button));
		}
		if (buttons.empty())
		{
			addDefaultButton();
		}
		else
		{
			const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel
			S32 button_panel_height = mControlPanel->getRect().getHeight();
			//try get an average h_pad to spread out buttons
			S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size()));
			if(h_pad < 2*HPAD)
			{
				/*
				 * Probably it is  a scriptdialog toast
				 * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
				 * In last case set default h_pad to avoid heaping of buttons 
				 */
				S32 button_per_row = button_panel_width / BUTTON_WIDTH;
				h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1  because we do not need space after last button in a row   
				if(h_pad < 2*HPAD) // still not enough space between buttons ?
				{
					h_pad = 2*HPAD;
				}
			}
			if (mIsScriptDialog)
			{
				// we are using default width for script buttons so we can determinate button_rows
				//to get a number of rows we divide the required width of the buttons to button_panel_width
				S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
				//S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
				//reserve one row for the ignore_btn
				button_rows++;
				//calculate required panel height for scripdialog notification.
				button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ IGNORE_BTN_TOP_DELTA + BOTTOM_PAD;
			}
			else
			{
				// in common case buttons can have different widths so we need to calculate button_rows according to buttons_width
				//S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width);
				S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width);
				//calculate required panel height 
				button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ BOTTOM_PAD;
			}
		
			// we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed
			adjustPanelForScriptNotice(button_panel_width, button_panel_height);
			updateButtonsLayout(buttons, h_pad);
			// save buttons for later use in disableButtons()
			mButtons.assign(buttons.begin(), buttons.end());
		}
	}
	// adjust panel's height to the text size
	mInfoPanel->setFollowsAll();
	snapToMessageHeight(mTextBox, MAX_LENGTH);

	if(notification->isReusable())
	{
		mButtonClickConnection = sButtonClickSignal.connect(
			boost::bind(&LLToastNotifyPanel::onToastPanelButtonClicked, this, _1, _2));

		if(notification->isRespondedTo())
		{
			// User selected an option in toast, now disable required buttons in IM window
			disableRespondedOptions(notification);
		}
	}
}
Пример #8
0
//---------------------------------------------------------------------------
// Singu Note: We could clean a lot of this up by creating derived classes for Notifications and NotificationTips.
LLNotifyBox::LLNotifyBox(LLNotificationPtr notification)
	:	LLPanel(notification->getName(), LLRect(), BORDER_NO),
		LLEventTimer(notification->getExpiration() == LLDate() 
			? LLDate(LLDate::now().secondsSinceEpoch() + (F64)gSavedSettings.getF32("NotifyTipDuration")) 
			: notification->getExpiration()),
		LLInstanceTracker<LLNotifyBox, LLUUID>(notification->getID()),
	  mNotification(notification),
	  mIsTip(notification->getType() == "notifytip"),
	  mAnimating(gNotifyBoxView->getChildCount() == 0), // Only animate first window
	  mNextBtn(NULL),
	  mNumOptions(0),
	  mNumButtons(0),
	  mAddedDefaultBtn(false),
	  mUserInputBox(NULL)
{
	std::string edit_text_name;
	std::string edit_text_contents;

	// setup paramaters
	const std::string& message(notification->getMessage());

	// initialize
	setFocusRoot(!mIsTip);

	// caution flag can be set explicitly by specifying it in the
	// notification payload, or it can be set implicitly if the
	// notify xml template specifies that it is a caution
	//
	// tip-style notification handle 'caution' differently -
	// they display the tip in a different color
	mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;

	LLNotificationFormPtr form(notification->getForm());

	mNumOptions = form->getNumElements();
		  
	bool is_textbox = form->getElement("message").isDefined();

	bool layout_script_dialog(notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup");
	LLRect rect = mIsTip ? getNotifyTipRect(message)
		   		  		 : getNotifyRect(is_textbox ? 10 : mNumOptions, layout_script_dialog, mIsCaution);
	setRect(rect);
	setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT));
	setBackgroundVisible(FALSE);
	setBackgroundOpaque(TRUE);

	LLIconCtrl* icon;
	LLTextEditor* text;

	const S32 TOP = getRect().getHeight() - (mIsTip ? (S32)sFont->getLineHeight() : 32);
	const S32 BOTTOM = (S32)sFont->getLineHeight();
	S32 x = HPAD + HPAD;
	S32 y = TOP;

	if (mIsTip)
	{
		// use the tip notification icon
		icon = new LLIconCtrl(std::string("icon"), LLRect(x, y, x+32, TOP-32), std::string("notify_tip_icon.tga"));
	}
	else if (mIsCaution)
	{
		// use the caution notification icon
		icon = new LLIconCtrl(std::string("icon"), LLRect(x, y, x+32, TOP-32), std::string("notify_caution_icon.tga"));
	}
	else
	{
		// use the default notification icon
		icon = new LLIconCtrl(std::string("icon"), LLRect(x, y, x+32, TOP-32), std::string("notify_box_icon.tga"));
	}

	icon->setMouseOpaque(FALSE);
	addChild(icon);

	x += HPAD + HPAD + 32;

	// add a caution textbox at the top of a caution notification
	LLTextBox* caution_box = NULL;
	if (mIsCaution && !mIsTip)
	{
		S32 caution_height = ((S32)sFont->getLineHeight() * 2) + VPAD;
		caution_box = new LLTextBox(
			std::string("caution_box"), 
			LLRect(x, y, getRect().getWidth() - 2, caution_height), 
			LLStringUtil::null, 
			sFont, 
			FALSE);

		caution_box->setFontStyle(LLFontGL::BOLD);
		caution_box->setColor(gColors.getColor("NotifyCautionWarnColor"));
		caution_box->setBackgroundColor(gColors.getColor("NotifyCautionBoxColor"));
		caution_box->setBorderVisible(FALSE);
		caution_box->setWrappedText(notification->getMessage());
		
		addChild(caution_box);

		// adjust the vertical position of the next control so that 
		// it appears below the caution textbox
		y = y - caution_height;
	}
	else if (mIsCaution && mIsTip)	
	{

		const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD);

		// Tokenization on \n is handled by LLTextBox

		const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;  // For script dialogs: add space for title.

		text = new LLTextEditor(std::string("box"), LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), MAX_LENGTH, message, sFont, FALSE);
		text->setWordWrap(TRUE);
		text->setTabStop(FALSE);
		text->setMouseOpaque(FALSE);
		text->setBorderVisible(FALSE);
		text->setTakesNonScrollClicks(FALSE);
		text->setHideScrollbarForShortDocs(TRUE);
		text->setReadOnlyBgColor ( LLColor4::transparent ); // the background color of the box is manually 
															// rendered under the text box, therefore we want 
															// the actual text box to be transparent
		text->setReadOnlyFgColor ( gColors.getColor("NotifyCautionWarnColor") ); //sets caution text color for tip notifications
		text->setEnabled(FALSE); // makes it read-only
		text->setTabStop(FALSE); // can't tab to it (may be a problem for scrolling via keyboard)
		addChild(text);
	}
	else
	{
		const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD);

		// Tokenization on \n is handled by LLTextBox
		const S32 MAX_LENGTH = 512 + 20 + 
			DB_FIRST_NAME_BUF_SIZE + 
			DB_LAST_NAME_BUF_SIZE +
			DB_INV_ITEM_NAME_BUF_SIZE;  // For script dialogs: add space for title.

		text = new LLTextEditor(std::string("box"),
								LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16),
								MAX_LENGTH,
								message,
								sFont,
								FALSE);
		text->setWordWrap(TRUE);
		text->setTabStop(FALSE);
		text->setMouseOpaque(FALSE);
		text->setBorderVisible(FALSE);
		text->setTakesNonScrollClicks(FALSE);
		text->setHideScrollbarForShortDocs(TRUE);
		text->setReadOnlyBgColor ( LLColor4::transparent ); // the background color of the box is manually 
															// rendered under the text box, therefore we want 
															// the actual text box to be transparent
		text->setReadOnlyFgColor ( gColors.getColor("NotifyTextColor") );
		text->setEnabled(FALSE); // makes it read-only
		text->setTabStop(FALSE); // can't tab to it (may be a problem for scrolling via keyboard)
		addChild(text);
	}

	if (mIsTip)
	{
		chat_notification(mNotification);
	}
	else
	{
		mNextBtn = new LLButton(std::string("next"),
						   LLRect(getRect().getWidth()-26, BOTTOM_PAD + 20, getRect().getWidth()-2, BOTTOM_PAD),
						   std::string("notify_next.png"),
						   std::string("notify_next.png"),
						   LLStringUtil::null,
						   boost::bind(&LLNotifyBox::moveToBack, this, true),
						   sFont);
		mNextBtn->setScaleImage(TRUE);
		mNextBtn->setToolTip(LLTrans::getString("next"));
		addChild(mNextBtn);

		for (S32 i = 0; i < mNumOptions; i++)
		{
			LLSD form_element = form->getElement(i);
			std::string element_type = form_element["type"].asString();
			if (element_type == "button") 
			{
				addButton(form_element["name"].asString(), form_element["text"].asString(), TRUE, form_element["default"].asBoolean(), layout_script_dialog);
			}
			else if (element_type == "input") 
			{
				edit_text_contents = form_element["value"].asString();
				edit_text_name = form_element["name"].asString();
			}
		}

		if (is_textbox)
		{
			S32 button_rows = layout_script_dialog ? 2 : 1;

			LLRect input_rect;
			input_rect.setOriginAndSize(x, BOTTOM_PAD + button_rows * (BTN_HEIGHT + VPAD),
										3 * 80 + 4 * HPAD, button_rows * (BTN_HEIGHT + VPAD) + BTN_HEIGHT);

			mUserInputBox = new LLTextEditor(edit_text_name, input_rect, 254,
											 edit_text_contents, sFont, FALSE);
			mUserInputBox->setBorderVisible(TRUE);
			mUserInputBox->setTakesNonScrollClicks(TRUE);
			mUserInputBox->setHideScrollbarForShortDocs(TRUE);
			mUserInputBox->setWordWrap(TRUE);
			mUserInputBox->setTabsToNextField(FALSE);
			mUserInputBox->setCommitOnFocusLost(FALSE);
			mUserInputBox->setAcceptCallingCardNames(FALSE);
			mUserInputBox->setHandleEditKeysDirectly(TRUE);

			addChild(mUserInputBox, -1);
		}
		else
		{
			setIsChrome(TRUE);
		}

		if (mNumButtons == 0)
		{
			addButton("OK", "OK", false, true, layout_script_dialog);
			mAddedDefaultBtn = true;
		}
		
		if (++sNotifyBoxCount <= 0)
			LL_WARNS() << "A notification was mishandled. sNotifyBoxCount = " << sNotifyBoxCount << LL_ENDL;
		// If this is the only notify box, don't show the next button
		else if (sNotifyBoxCount == 1 && mNextBtn)
			mNextBtn->setVisible(false);
	}
}
Пример #9
0
//---------------------------------------------------------------------------
// Singu Note: We could clean a lot of this up by creating derived classes for Notifications and NotificationTips.
LLNotifyBox::LLNotifyBox(LLNotificationPtr notification)
	:	LLPanel(notification->getName(), LLRect(), BORDER_NO),
		LLEventTimer(notification->getExpiration() == LLDate() 
			? LLDate(LLDate::now().secondsSinceEpoch() + (F64)gSavedSettings.getF32("NotifyTipDuration")) 
			: notification->getExpiration()),
		LLInstanceTracker<LLNotifyBox, LLUUID>(notification->getID()),
	  mNotification(notification),
	  mIsTip(notification->getType() == "notifytip"),
	  mAnimating(gNotifyBoxView->getChildCount() == 0), // Only animate first window
	  mNextBtn(NULL),
	  mNumOptions(0),
	  mNumButtons(0),
	  mAddedDefaultBtn(false),
	  mUserInputBox(NULL)
{
	std::string edit_text_name;
	std::string edit_text_contents;

	// setup paramaters
	const std::string& message(notification->getMessage());

	// initialize
	setFocusRoot(!mIsTip);

	// caution flag can be set explicitly by specifying it in the
	// notification payload, or it can be set implicitly if the
	// notify xml template specifies that it is a caution
	//
	// tip-style notification handle 'caution' differently -
	// they display the tip in a different color
	mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;

	LLNotificationFormPtr form(notification->getForm());

	mNumOptions = form->getNumElements();
		  
	bool is_textbox = form->getElement("message").isDefined();

	bool layout_script_dialog(notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup");
	LLRect rect = mIsTip ? getNotifyTipRect(message)
		   		  		 : getNotifyRect(is_textbox ? 10 : mNumOptions, layout_script_dialog, mIsCaution);
	if ((form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE || form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE))
		rect.mBottom -= BTN_HEIGHT;
	setRect(rect);
	setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT));
	setBackgroundVisible(FALSE);
	setBackgroundOpaque(TRUE);

	const S32 TOP = getRect().getHeight() - (mIsTip ? (S32)sFont->getLineHeight() : 32);
	const S32 BOTTOM = (S32)sFont->getLineHeight();
	S32 x = HPAD + HPAD;
	S32 y = TOP;

	auto icon = new LLIconCtrl(std::string("icon"), LLRect(x, y, x+32, TOP-32), mIsTip ? "notify_tip_icon.tga" : mIsCaution ? "notify_caution_icon.tga" : "notify_box_icon.tga");

	icon->setMouseOpaque(FALSE);
	addChild(icon);

	x += HPAD + HPAD + 32;

	// add a caution textbox at the top of a caution notification
	if (mIsCaution && !mIsTip)
	{
		S32 caution_height = ((S32)sFont->getLineHeight() * 2) + VPAD;
		auto caution_box = new LLTextBox(
			std::string("caution_box"), 
			LLRect(x, y, getRect().getWidth() - 2, caution_height), 
			LLStringUtil::null, 
			sFont, 
			FALSE);

		caution_box->setFontStyle(LLFontGL::BOLD);
		caution_box->setColor(gColors.getColor("NotifyCautionWarnColor"));
		caution_box->setBackgroundColor(gColors.getColor("NotifyCautionBoxColor"));
		caution_box->setBorderVisible(FALSE);
		caution_box->setWrappedText(notification->getMessage());
		
		addChild(caution_box);

		// adjust the vertical position of the next control so that 
		// it appears below the caution textbox
		y = y - caution_height;
	}
	else
	{
		const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD);

		// Tokenization on \n is handled by LLTextBox

		const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;  // For script dialogs: add space for title.

		auto text = new LLTextEditor(std::string("box"), LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), MAX_LENGTH, LLStringUtil::null, sFont, FALSE, true);
		text->setWordWrap(TRUE);
		text->setMouseOpaque(TRUE);
		text->setBorderVisible(FALSE);
		text->setTakesNonScrollClicks(TRUE);
		text->setHideScrollbarForShortDocs(TRUE);
		text->setReadOnlyBgColor ( LLColor4::transparent ); // the background color of the box is manually 
															// rendered under the text box, therefore we want 
															// the actual text box to be transparent

		auto text_color = gColors.getColor(mIsCaution && mIsTip ? "NotifyCautionWarnColor" : "NotifyTextColor");
		text->setReadOnlyFgColor(text_color); //sets caution text color for tip notifications
		if (!mIsCaution) // We could do some extra color math here to determine if bg's too close to link color, but let's just cross with the link color instead
			text->setLinkColor(new LLColor4(lerp(text_color, gSavedSettings.getColor4("HTMLLinkColor"), 0.4f)));
		text->setTabStop(FALSE); // can't tab to it (may be a problem for scrolling via keyboard)
		text->appendText(message,false,false,nullptr,!layout_script_dialog); // Now we can set the text, since colors have been set.
		addChild(text);
	}

	if (mIsTip)
	{
		chat_notification(mNotification);
	}
	else
	{
		mNextBtn = new LLButton(std::string("next"),
						   LLRect(getRect().getWidth()-26, BOTTOM_PAD + 20, getRect().getWidth()-2, BOTTOM_PAD),
						   std::string("notify_next.png"),
						   std::string("notify_next.png"),
						   LLStringUtil::null,
						   boost::bind(&LLNotifyBox::moveToBack, this, true),
						   sFont);
		mNextBtn->setScaleImage(TRUE);
		mNextBtn->setToolTip(LLTrans::getString("next"));
		addChild(mNextBtn);

		for (S32 i = 0; i < mNumOptions; i++)
		{
			LLSD form_element = form->getElement(i);
			std::string element_type = form_element["type"].asString();
			if (element_type == "button") 
			{
				addButton(form_element["name"].asString(), form_element["text"].asString(), TRUE, form_element["default"].asBoolean(), layout_script_dialog);
			}
			else if (element_type == "input") 
			{
				edit_text_contents = form_element["value"].asString();
				edit_text_name = form_element["name"].asString();
			}
		}

		if (is_textbox)
		{
			S32 button_rows = layout_script_dialog ? 2 : 1;

			LLRect input_rect;
			input_rect.setOriginAndSize(x, BOTTOM_PAD + button_rows * (BTN_HEIGHT + VPAD),
										3 * 80 + 4 * HPAD, button_rows * (BTN_HEIGHT + VPAD) + BTN_HEIGHT);

			mUserInputBox = new LLTextEditor(edit_text_name, input_rect, 254,
											 edit_text_contents, sFont, FALSE);
			mUserInputBox->setBorderVisible(TRUE);
			mUserInputBox->setTakesNonScrollClicks(TRUE);
			mUserInputBox->setHideScrollbarForShortDocs(TRUE);
			mUserInputBox->setWordWrap(TRUE);
			mUserInputBox->setTabsToNextField(FALSE);
			mUserInputBox->setCommitOnFocusLost(FALSE);
			mUserInputBox->setAcceptCallingCardNames(FALSE);
			mUserInputBox->setHandleEditKeysDirectly(TRUE);

			addChild(mUserInputBox, -1);
		}
		else
		{
			setIsChrome(TRUE);
		}

		if (mNumButtons == 0)
		{
			addButton("OK", "OK", false, true, layout_script_dialog);
			mAddedDefaultBtn = true;
		}

		std::string check_title;
		if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
		{
			check_title = LLNotificationTemplates::instance().getGlobalString("skipnexttime");
		}
		else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
		{
			check_title = LLNotificationTemplates::instance().getGlobalString("alwayschoose");
		}
		if (!check_title.empty())
		{
			const LLFontGL* font = LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF);
			S32 line_height = llfloor(font->getLineHeight() + 0.99f);

			// Extend dialog for "check next time"
			S32 max_msg_width = getRect().getWidth() - HPAD * 9;
			S32 check_width = S32(font->getWidth(check_title) + 0.99f) + 16;
			max_msg_width = llmax(max_msg_width, check_width);

			S32 msg_x = (getRect().getWidth() - max_msg_width) / 2;

			LLRect check_rect;
			check_rect.setOriginAndSize(msg_x, BOTTOM_PAD + BTN_HEIGHT + VPAD*2 + (BTN_HEIGHT + VPAD) * (mNumButtons / 3),
				max_msg_width, line_height);

			LLCheckboxCtrl* check = new LLCheckboxCtrl(std::string("check"), check_rect, check_title, font,
				// Lambda abuse.
				[this](LLUICtrl* ctrl, const LLSD& param)
				{
						this->mNotification->setIgnored(ctrl->getValue());
				});
			check->setEnabledColor(LLUI::sColorsGroup->getColor(mIsCaution ? "AlertCautionTextColor" : "AlertTextColor"));
			if (mIsCaution)
			{
				check->setButtonColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor"));
			}
			addChild(check);
		}
		
		if (++sNotifyBoxCount <= 0)
			LL_WARNS() << "A notification was mishandled. sNotifyBoxCount = " << sNotifyBoxCount << LL_ENDL;
		// If this is the only notify box, don't show the next button
		else if (sNotifyBoxCount == 1 && mNextBtn)
			mNextBtn->setVisible(false);
	}
}
		bool matches(const LLNotificationPtr notification) const
		{
			// "notifytoast" type of notifications is reserved for IM notifications
			return "notifytoast" == notification->getType();
		}
Пример #11
0
//---------------------------------------------------------------------------
LLNotifyBox::LLNotifyBox(LLNotificationPtr notification,
						 BOOL layout_script_dialog)
	:	LLPanel(notification->getName(), LLRect(), BORDER_NO),
		LLEventTimer(notification->getExpiration() == LLDate() 
			? LLDate(LLDate::now().secondsSinceEpoch() + (F64)gSavedSettings.getF32("NotifyTipDuration")) 
			: notification->getExpiration()),
		LLInstanceTracker<LLNotifyBox, LLUUID>(notification->getID()),
	  mNotification(notification),
	  mIsTip(notification->getType() == "notifytip"),
	  mAnimating(TRUE),
	  mNextBtn(NULL),
	  mNumOptions(0),
	  mNumButtons(0),
	  mAddedDefaultBtn(FALSE),
	  mLayoutScriptDialog(layout_script_dialog)
{
	// clicking on a button does not steal current focus
	setIsChrome(TRUE);

	// class init
	if (!sFont)
	{
		sFont = LLFontGL::getFontSansSerif();
		sFontSmall = LLFontGL::getFontSansSerifSmall();
	}

	// setup paramaters
	mMessage = notification->getMessage();

	// initialize
	setFocusRoot(!mIsTip);

	// caution flag can be set explicitly by specifying it in the
	// notification payload, or it can be set implicitly if the
	// notify xml template specifies that it is a caution
	//
	// tip-style notification handle 'caution' differently -
	// they display the tip in a different color
	mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;

	// Only animate first window
	if( gNotifyBoxView->getChildCount() > 0 )
		mAnimating = FALSE;
	else
		mAnimating = TRUE;

	LLNotificationFormPtr form(notification->getForm());

	mNumOptions = form->getNumElements();
		  
	LLRect rect = mIsTip ? getNotifyTipRect(mMessage)
		   		  		 : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution);
	setRect(rect);
	setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT));
	setBackgroundVisible(FALSE);
	setBackgroundOpaque(TRUE);

	LLIconCtrl* icon;
	LLTextEditor* text;

	const S32 TOP = getRect().getHeight() - (mIsTip ? (S32)sFont->getLineHeight() : 32);
	const S32 BOTTOM = (S32)sFont->getLineHeight();
	S32 x = HPAD + HPAD;
	S32 y = TOP;

	if (mIsTip)
	{
		// use the tip notification icon
		icon = new LLIconCtrl(std::string("icon"), LLRect(x, y, x+32, TOP-32), std::string("notify_tip_icon.tga"));
	}
	else if (mIsCaution)
	{
		// use the caution notification icon
		icon = new LLIconCtrl(std::string("icon"), LLRect(x, y, x+32, TOP-32), std::string("notify_caution_icon.tga"));
	}
	else
	{
		// use the default notification icon
		icon = new LLIconCtrl(std::string("icon"), LLRect(x, y, x+32, TOP-32), std::string("notify_box_icon.tga"));
	}

	icon->setMouseOpaque(FALSE);
	addChild(icon);

	x += HPAD + HPAD + 32;

	// add a caution textbox at the top of a caution notification
	LLTextBox* caution_box = NULL;
	if (mIsCaution && !mIsTip)
	{
		S32 caution_height = ((S32)sFont->getLineHeight() * 2) + VPAD;
		caution_box = new LLTextBox(
			std::string("caution_box"), 
			LLRect(x, y, getRect().getWidth() - 2, caution_height), 
			LLStringUtil::null, 
			sFont, 
			FALSE);

		caution_box->setFontStyle(LLFontGL::BOLD);
		caution_box->setColor(gColors.getColor("NotifyCautionWarnColor"));
		caution_box->setBackgroundColor(gColors.getColor("NotifyCautionBoxColor"));
		caution_box->setBorderVisible(FALSE);
		caution_box->setWrappedText(notification->getMessage());
		
		addChild(caution_box);

		// adjust the vertical position of the next control so that 
		// it appears below the caution textbox
		y = y - caution_height;
	}
	else
	{

		const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD);

		// Tokenization on \n is handled by LLTextBox

		const S32 MAX_LENGTH = 512 + 20 + 
			DB_FIRST_NAME_BUF_SIZE + 
			DB_LAST_NAME_BUF_SIZE +
			DB_INV_ITEM_NAME_BUF_SIZE;  // For script dialogs: add space for title.

		text = new LLTextEditor(std::string("box"),
								LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16),
								MAX_LENGTH,
								mMessage,
								sFont,
								FALSE);
		text->setWordWrap(TRUE);
		text->setTabStop(FALSE);
		text->setMouseOpaque(FALSE);
		text->setBorderVisible(FALSE);
		text->setTakesNonScrollClicks(FALSE);
		text->setHideScrollbarForShortDocs(TRUE);
		text->setReadOnlyBgColor ( LLColor4::transparent ); // the background color of the box is manually 
															// rendered under the text box, therefore we want 
															// the actual text box to be transparent
		text->setReadOnlyFgColor ( gColors.getColor("NotifyTextColor") );
		text->setEnabled(FALSE); // makes it read-only
		text->setTabStop(FALSE); // can't tab to it (may be a problem for scrolling via keyboard)
		addChild(text);
	}

	if (mIsTip)
	{
		// TODO: Make a separate archive for these.
		LLChat chat(mMessage);
		chat.mSourceType = CHAT_SOURCE_SYSTEM;
		LLFloaterChat::getInstance(LLSD())->addChatHistory(chat);
	}
	else
	{
		LLButton* btn;
		btn = new LLButton(std::string("next"),
						   LLRect(getRect().getWidth()-26, BOTTOM_PAD + 20, getRect().getWidth()-2, BOTTOM_PAD),
						   std::string("notify_next.png"),
						   std::string("notify_next.png"),
						   LLStringUtil::null,
						   onClickNext,
						   this,
						   sFont);
		btn->setScaleImage(TRUE);
		btn->setToolTip(std::string("Next")); // *TODO: Translate
		addChild(btn);
		mNextBtn = btn;

		for (S32 i = 0; i < mNumOptions; i++)
		{

			LLSD form_element = form->getElement(i);
			if (form_element["type"].asString() != "button") 
			{
				continue;
			}

			addButton(form_element["name"].asString(), form_element["text"].asString(), TRUE, form_element["default"].asBoolean());
		}

		if (mNumButtons == 0)
		{
			addButton("OK", "OK", FALSE, TRUE);
			mAddedDefaultBtn = TRUE;
		}
		
		sNotifyBoxCount++;

		if (sNotifyBoxCount <= 0)
		{
			llwarns << "A notification was mishandled. sNotifyBoxCount = " << sNotifyBoxCount << llendl;
		}
		
		// If this is the only notify box, don't show the next button
		if (sNotifyBoxCount == 1
			&& mNextBtn)
		{
			mNextBtn->setVisible(FALSE);
		}
	}
}