diff options
| -rw-r--r-- | indra/llui/llnotifications.cpp | 91 | ||||
| -rw-r--r-- | indra/llui/llnotifications.h | 55 | ||||
| -rw-r--r-- | indra/llui/llnotificationslistener.cpp | 7 | ||||
| -rw-r--r-- | indra/llui/llnotificationtemplate.h | 10 | ||||
| -rw-r--r-- | indra/llxuixml/llinitparam.cpp | 2 | ||||
| -rw-r--r-- | indra/llxuixml/llinitparam.h | 18 | ||||
| -rw-r--r-- | indra/newview/llbrowsernotification.cpp | 18 | ||||
| -rw-r--r-- | indra/newview/llfloatermediabrowser.cpp | 109 | ||||
| -rw-r--r-- | indra/newview/llfloatermediabrowser.h | 6 | ||||
| -rw-r--r-- | indra/newview/llfloaterpreference.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llhints.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llmediactrl.cpp | 208 | ||||
| -rw-r--r-- | indra/newview/llmediactrl.h | 10 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_media_browser.xml | 70 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 104 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_preferences_setup.xml | 14 | 
16 files changed, 410 insertions, 324 deletions
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index bdc094bf47..bd58fe2637 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -55,6 +55,47 @@ void NotificationPriorityValues::declareValues()  	declare("critical", NOTIFICATION_PRIORITY_CRITICAL);  } +LLNotificationForm::FormElementBase::FormElementBase() +:	name("name") +{} + +LLNotificationForm::FormIgnore::FormIgnore() +:	text("text"), +	control("control"), +	invert_control("invert_control", false), +	save_option("save_option", false) +{} + +LLNotificationForm::FormButton::FormButton() +:	index("index"), +	text("text"), +	ignore("ignore"), +	is_default("default"), +	type("type") +{ +	// set type here so it gets serialized +	type = "button"; +} + +LLNotificationForm::FormInput::FormInput() +:	type("type"), +	width("width", 0) +{} + +LLNotificationForm::FormElement::FormElement() +:	button("button"), +	input("input") +{} + +LLNotificationForm::FormElements::FormElements() +:	elements("") +{} + +LLNotificationForm::Params::Params() +:	name("name"), +	ignore("ignore"), +	form_elements("") +{}  // Local channel for persistent notifications  // Stores only persistent notifications. @@ -100,12 +141,7 @@ bool filterIgnoredNotifications(LLNotificationPtr notification)  	LLNotificationFormPtr form = notification->getForm();  	// Check to see if the user wants to ignore this alert -	if (form->getIgnoreType() != LLNotificationForm::IGNORE_NO) -	{ -		return LLUI::sSettingGroups["ignores"]->getBOOL(notification->getName()); -	} - -	return true; +	return !notification->getForm()->getIgnored();  }  bool handleIgnoredNotification(const LLSD& payload) @@ -153,7 +189,8 @@ LLNotificationForm::LLNotificationForm()  LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotificationForm::Params& p)  -:	mIgnore(IGNORE_NO) +:	mIgnore(IGNORE_NO), +	mInvertSetting(false)  {  	if (p.ignore.isProvided())  	{ @@ -171,7 +208,16 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica  		}  		BOOL show_notification = TRUE; -		LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Ignore notification with this name", TRUE); +		if (p.ignore.control.isProvided()) +		{ +			mIgnoreSetting = LLUI::sSettingGroups["config"]->getControl(p.ignore.control); +			mInvertSetting = p.ignore.invert_control; +		} +		else +		{ +			LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Ignore notification with this name", TRUE); +			mIgnoreSetting = LLUI::sSettingGroups["ignores"]->getControl(name); +		}  	}  	LLParamSDParser parser; @@ -300,6 +346,27 @@ std::string LLNotificationForm::getDefaultOption()  	return "";  } +LLControlVariablePtr LLNotificationForm::getIgnoreSetting()  +{  +	return mIgnoreSetting;  +} + +bool LLNotificationForm::getIgnored() +{ +	if (mIgnore != LLNotificationForm::IGNORE_NO +		&& mIgnoreSetting)  +	{ +		return mIgnoreSetting->getValue().asBoolean() != mInvertSetting; +	} + +	return false; +} + +void LLNotificationForm::setIgnored(bool ignored) +{ +	if (mIgnoreSetting) mIgnoreSetting->setValue(ignored != mInvertSetting); +} +  LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Params& p)  :	mName(p.name),  	mType(p.type), @@ -545,8 +612,8 @@ void LLNotification::respond(const LLSD& response)  	if (mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)  	{ -		BOOL show_notification = mIgnored ? FALSE : TRUE; -		LLUI::sSettingGroups["ignores"]->setBOOL(getName(), show_notification); +		bool show_notification = !mIgnored; +		mForm->setIgnored(!show_notification);  		if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)  		{  			LLUI::sSettingGroups["ignores"]->setLLSD("Default" + getName(), response); @@ -1294,11 +1361,11 @@ bool LLNotifications::loadTemplates()  			}  			if(it->form_ref.form_template.cancel_text.isProvided())  			{ -				replaceFormText(it->form_ref.form, "$cancel_text", it->form_ref.form_template.cancel_text); +				replaceFormText(it->form_ref.form, "$canceltext", it->form_ref.form_template.cancel_text);  			}  			if(it->form_ref.form_template.ignore_text.isProvided())  			{ -				replaceFormText(it->form_ref.form, "$ignore_text", it->form_ref.form_template.ignore_text); +				replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text);  			}  		}  		addTemplate(it->name, LLNotificationTemplatePtr(new LLNotificationTemplate(*it))); diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index a58e7afe23..ed29e0d83e 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -163,22 +163,19 @@ class LLNotificationForm  public:  	struct FormElementBase : public LLInitParam::Block<FormElementBase>  	{ -		Mandatory<std::string>	name; +		Optional<std::string>	name; -		FormElementBase() -		:	name("name") -		{} +		FormElementBase();  	};  	struct FormIgnore : public LLInitParam::Block<FormIgnore, FormElementBase>  	{  		Optional<std::string>	text;  		Optional<bool>			save_option; +		Optional<std::string>	control; +		Optional<bool>			invert_control; -		FormIgnore() -		:	text("text"), -			save_option("save_option", false) -		{} +		FormIgnore();  	};  	struct FormButton : public LLInitParam::Block<FormButton, FormElementBase> @@ -190,16 +187,7 @@ public:  		Mandatory<std::string>	type; -		FormButton() -		:	index("index"), -			text("text"), -			ignore("ignore"), -			is_default("default"), -			type("type") -		{ -			// set type here so it gets serialized -			type = "button"; -		} +		FormButton();  	};  	struct FormInput : public LLInitParam::Block<FormInput, FormElementBase> @@ -207,10 +195,7 @@ public:  		Mandatory<std::string>	type;  		Optional<S32>			width; -		FormInput() -		:	type("type"), -			width("width", 0) -		{} +		FormInput();  	};  	struct FormElement : public LLInitParam::Choice<FormElement> @@ -218,18 +203,13 @@ public:  		Alternative<FormButton> button;  		Alternative<FormInput>	input; -		FormElement() -		:	button("button"), -			input("input") -		{} +		FormElement();  	};  	struct FormElements : public LLInitParam::Block<FormElements>  	{  		Multiple<FormElement> elements; -		FormElements() -		:	elements("") -		{} +		FormElements();  	};  	struct Params : public LLInitParam::Block<Params> @@ -238,11 +218,7 @@ public:  		Optional<FormIgnore>	ignore;  		Optional<FormElements>	form_elements; -		Params() -		:	name("name"), -			ignore("ignore"), -			form_elements("") -		{} +		Params();  	};  	typedef enum e_ignore_type @@ -268,14 +244,19 @@ public:  	// appends form elements from another form serialized as LLSD  	void append(const LLSD& sub_form);  	std::string getDefaultOption(); +	LLPointer<class LLControlVariable> getIgnoreSetting(); +	bool getIgnored(); +	void setIgnored(bool ignored);  	EIgnoreType getIgnoreType() { return mIgnore; }  	std::string getIgnoreMessage() { return mIgnoreMsg; }  private: -	LLSD	mFormData; -	EIgnoreType mIgnore; -	std::string mIgnoreMsg; +	LLSD								mFormData; +	EIgnoreType							mIgnore; +	std::string							mIgnoreMsg; +	LLPointer<class LLControlVariable>	mIgnoreSetting; +	bool								mInvertSetting;  };  typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr; diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp index 44a90398fd..3bbeb3a778 100644 --- a/indra/llui/llnotificationslistener.cpp +++ b/indra/llui/llnotificationslistener.cpp @@ -29,6 +29,7 @@  #include "linden_common.h"  #include "llnotificationslistener.h"  #include "llnotifications.h" +#include "llnotificationtemplate.h"  #include "llsd.h"  #include "llui.h" @@ -182,7 +183,11 @@ void LLNotificationsListener::ignore(const LLSD& params) const      if (params["name"].isDefined())      {          // ["name"] was passed: ignore just that notification -        LLUI::sSettingGroups["ignores"]->setBOOL(params["name"], ignore); +		LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]); +		if (templatep) +		{ +			templatep->mForm->setIgnored(ignore); +		}      }      else      { diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h index 4a020bfe70..a4d393f874 100644 --- a/indra/llui/llnotificationtemplate.h +++ b/indra/llui/llnotificationtemplate.h @@ -74,10 +74,18 @@ struct LLNotificationTemplate  	struct UniquenessContext : public LLInitParam::Block<UniquenessContext>  	{ +	private: +		// this idiom allows  +		// <notification unique="true"> +		// as well as +		// <notification> <unique> <context key=""/> </unique>... +		Optional<bool>			dummy_val; +	public:  		Mandatory<std::string>	key;  		UniquenessContext() -		:	key("key") +		:	key("key"), +			dummy_val("")  		{}  	}; diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp index dc4d93d38a..2c92539387 100644 --- a/indra/llxuixml/llinitparam.cpp +++ b/indra/llxuixml/llinitparam.cpp @@ -178,7 +178,7 @@ namespace LLInitParam  			param_handle_t param_handle = it->second->mParamHandle;  			const Param* param = getParamFromHandle(param_handle);  			ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc; -			if (serialize_func && param->getProvided()) +			if (serialize_func && param->anyProvided())  			{  				// Ensure this param has not already been serialized  				// Prevents <rect> from being serialized as its own tag. diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 610381dcfe..24ce891880 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -287,7 +287,7 @@ namespace LLInitParam  		void setProvided(bool is_provided) { mIsProvided = is_provided; }  	protected: -		bool getProvided() const { return mIsProvided; } +		bool anyProvided() const { return mIsProvided; }  		Param(class BaseBlock* enclosing_block); @@ -568,7 +568,7 @@ namespace LLInitParam  			mData.mValue = value;  		}  -		bool isProvided() const { return Param::getProvided(); } +		bool isProvided() const { return Param::anyProvided(); }  		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)   		{  @@ -795,13 +795,13 @@ namespace LLInitParam  		bool isProvided() const   		{   			// only validate block when it hasn't already passed validation and user has supplied *some* value -			if (Param::getProvided() && mData.mValidatedVersion < T::getLastChangeVersion()) +			if (Param::anyProvided() && mData.mValidatedVersion < T::getLastChangeVersion())  			{  				// a sub-block is "provided" when it has been filled in enough to be valid  				mData.mValidated = T::validateBlock(false);  				mData.mValidatedVersion = T::getLastChangeVersion();  			} -			return Param::getProvided() && mData.mValidated; +			return Param::anyProvided() && mData.mValidated;  		}  		// assign block contents to this param-that-is-a-block @@ -852,7 +852,7 @@ namespace LLInitParam  		{  			const self_t& src_typed_param = static_cast<const self_t&>(src);  			self_t& dst_typed_param = static_cast<self_t&>(dst); -			if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite || !dst_typed_param.isProvided())) +			if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite))  			{  				dst_typed_param.mData.clearKey();  				return true; @@ -909,7 +909,7 @@ namespace LLInitParam  			}  		}  -		bool isProvided() const { return Param::getProvided(); } +		bool isProvided() const { return Param::anyProvided(); }  		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)   		{  @@ -1093,7 +1093,7 @@ namespace LLInitParam  			}  		}  -		bool isProvided() const { return Param::getProvided(); } +		bool isProvided() const { return Param::anyProvided(); }  		value_ref_t operator[](S32 index) { return mValues[index]; }  		value_const_ref_t operator[](S32 index) const { return mValues[index]; } @@ -1736,7 +1736,7 @@ namespace LLInitParam  		bool isProvided() const   		{ -			if (!Param::getProvided()) return false; +			if (!Param::anyProvided()) return false;  			// block has an updated parameter  			// if cached value is stale, regenerate from params @@ -1803,7 +1803,7 @@ namespace LLInitParam  		value_assignment_t get() const  		{  			// if some parameters were provided, issue warnings on invalid blocks -			if (Param::getProvided() && (mData.mValueAge == OLDER_THAN_BLOCK)) +			if (Param::anyProvided() && (mData.mValueAge == OLDER_THAN_BLOCK))  			{  				// go ahead and issue warnings at this point if any param is invalid  				if(block_t::validateBlock(true)) diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp index e162527e23..cc54d10944 100644 --- a/indra/newview/llbrowsernotification.cpp +++ b/indra/newview/llbrowsernotification.cpp @@ -36,22 +36,6 @@ using namespace LLNotificationsUI;  bool LLBrowserNotification::processNotification(const LLSD& notify)  { -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - -	if (notification) -	{ -		LLFloaterMediaBrowser* browserp = dynamic_cast<LLFloaterMediaBrowser*>(LLFloaterReg::findInstance("media_browser", notification->getPayload()["source"])); -		if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load") -		{ -			if (browserp) -			{ -				browserp->showNotification(notification); -			} -		} -		else if (notify["sigtype"].asString() == "delete") -		{ -			browserp->hideNotification(); -		} -	} +	// browser notifications are currently handled directly by the LLMediaCtrl instance that spawned them  	return false;  } diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp index 751304588b..d20092e344 100644 --- a/indra/newview/llfloatermediabrowser.cpp +++ b/indra/newview/llfloatermediabrowser.cpp @@ -74,11 +74,11 @@ void LLFloaterMediaBrowser::create(const std::string &url, const std::string& ta  		}  		else  		{ -			// create a unique tag for this instance -			LLUUID id; -			id.generate(); -			tag = id.asString(); -		} +		// create a unique tag for this instance +		LLUUID id; +		id.generate(); +		tag = id.asString(); +	}  	}  	S32 browser_window_limit = gSavedSettings.getS32("MediaBrowserWindowLimit"); @@ -149,8 +149,8 @@ void LLFloaterMediaBrowser::geometryChanged(const std::string &uuid, S32 x, S32  		{  			i->geometryChanged(x, y, width, height);  			return; - 		} - 	} +	} +}  }  void LLFloaterMediaBrowser::geometryChanged(S32 x, S32 y, S32 width, S32 height) @@ -213,16 +213,12 @@ void LLFloaterMediaBrowser::draw()  BOOL LLFloaterMediaBrowser::postBuild()  {  	mBrowser = getChild<LLMediaCtrl>("browser"); -	mBrowser->setMediaID(mKey);  	mBrowser->addObserver(this);  	mAddressCombo = getChild<LLComboBox>("address");  	mAddressCombo->setCommitCallback(onEnterAddress, this);  	mAddressCombo->sortByName(); -	LLButton& notification_close = getChildRef<LLButton>("close_notification"); -	notification_close.setClickedCallback(boost::bind(&LLFloaterMediaBrowser::onCloseNotification, this), NULL); -  	childSetAction("back", onClickBack, this);  	childSetAction("forward", onClickForward, this);  	childSetAction("reload", onClickRefresh, this); @@ -326,73 +322,6 @@ void LLFloaterMediaBrowser::setCurrentURL(const std::string& url)  	getChildView("reload")->setEnabled(TRUE);  } -void LLFloaterMediaBrowser::showNotification(LLNotificationPtr notify) -{ -	mCurNotification = notify; - -	// add popup here -	LLSD payload = notify->getPayload(); - -	LLNotificationFormPtr formp = notify->getForm(); -	LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area"); -	panel.setVisible(true); -	panel.getChild<LLUICtrl>("notification_icon")->setValue(notify->getIcon()); -	panel.getChild<LLUICtrl>("notification_text")->setValue(notify->getMessage()); -	panel.getChild<LLUICtrl>("notification_text")->setToolTip(notify->getMessage()); -	LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType();  -	LLLayoutPanel& form_elements = panel.getChildRef<LLLayoutPanel>("form_elements"); - -	const S32 FORM_PADDING_HORIZONTAL = 10; -	const S32 FORM_PADDING_VERTICAL = 5; -	S32 cur_x = FORM_PADDING_HORIZONTAL; - -	if (ignore_type != LLNotificationForm::IGNORE_NO) -	{ -		LLCheckBoxCtrl::Params checkbox_p; -		checkbox_p.name = "ignore_check"; -		checkbox_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL); -		checkbox_p.label = formp->getIgnoreMessage(); -		checkbox_p.label_text.text_color = LLColor4::black; -		checkbox_p.commit_callback.function = boost::bind(&LLFloaterMediaBrowser::onClickIgnore, this, _1); - -		LLCheckBoxCtrl* check = LLUICtrlFactory::create<LLCheckBoxCtrl>(checkbox_p); -		check->setRect(check->getBoundingRect()); -		form_elements.addChild(check); -		cur_x = check->getRect().mRight + FORM_PADDING_HORIZONTAL; -	} - -	for (S32 i = 0; i < formp->getNumElements(); i++) -	{ -		LLSD form_element = formp->getElement(i); -		if (form_element["type"].asString() == "button") -		{ -			LLButton::Params button_p; -			button_p.name = form_element["name"]; -			button_p.label = form_element["text"]; -			button_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL); -			button_p.commit_callback.function = boost::bind(&LLFloaterMediaBrowser::onClickNotificationButton, this, form_element["name"].asString()); -			button_p.auto_resize = true; - -			LLButton* button = LLUICtrlFactory::create<LLButton>(button_p); -			button->autoResize(); -			form_elements.addChild(button); - -			cur_x = button->getRect().mRight + FORM_PADDING_HORIZONTAL; -		} -	} - - -	form_elements.reshape(cur_x, form_elements.getRect().getHeight()); - -	//LLWeb::loadURL(payload["url"], payload["target"]); -} - -void LLFloaterMediaBrowser::hideNotification() -{ -	LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area"); -	panel.setVisible(FALSE); -} -  //static   void LLFloaterMediaBrowser::onEnterAddress(LLUICtrl* ctrl, void* user_data)  { @@ -526,28 +455,4 @@ void LLFloaterMediaBrowser::openMedia(const std::string& media_url, const std::s  	setCurrentURL(media_url);  } -void LLFloaterMediaBrowser::onCloseNotification() -{ -	LLNotifications::instance().cancel(mCurNotification); -} -void LLFloaterMediaBrowser::onClickIgnore(LLUICtrl* ctrl) -{ -	bool check = ctrl->getValue().asBoolean(); -	if (mCurNotification && mCurNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN) -	{ -		// question was "show again" so invert value to get "ignore" -		check = !check; -	} -	mCurNotification->setIgnored(check); -} - -void LLFloaterMediaBrowser::onClickNotificationButton(const std::string& name) -{ -	if (!mCurNotification) return; - -	LLSD response = mCurNotification->getResponseTemplate(); -	response[name] = true; - -	mCurNotification->respond(response);  -} diff --git a/indra/newview/llfloatermediabrowser.h b/indra/newview/llfloatermediabrowser.h index 1a6f3a0352..152d221a01 100644 --- a/indra/newview/llfloatermediabrowser.h +++ b/indra/newview/llfloatermediabrowser.h @@ -60,8 +60,6 @@ public:  	void buildURLHistory();  	std::string getSupportURL();  	void setCurrentURL(const std::string& url); -	void showNotification(boost::shared_ptr<LLNotification> notify); -	void hideNotification();  	static void onEnterAddress(LLUICtrl* ctrl, void* user_data);  	static void onClickRefresh(void* user_data); @@ -77,10 +75,6 @@ public:  	static void onClickSeek(void* user_data);  private: -	void onCloseNotification(); -	void onClickIgnore(LLUICtrl* ctrl); -	void onClickNotificationButton(const std::string& name); -  	LLMediaCtrl* mBrowser;  	LLComboBox* mAddressCombo;  	std::string mCurrentURL; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 50aacc6458..cba91d7e7e 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -798,7 +798,7 @@ void LLFloaterPreference::buildPopupLists()  		LLScrollListItem* item = NULL; -		bool show_popup = LLUI::sSettingGroups["ignores"]->getBOOL(templatep->mName); +		bool show_popup = formp->getIgnored();  		if (!show_popup)  		{  			if (ignore == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) @@ -1150,9 +1150,7 @@ void LLFloaterPreference::onClickDisablePopup()  	for (itor = items.begin(); itor != items.end(); ++itor)  	{  		LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata())); -		//gSavedSettings.setWarning(templatep->mName, TRUE); -		std::string notification_name = templatep->mName; -		LLUI::sSettingGroups["ignores"]->setBOOL(notification_name, FALSE); +		templatep->mForm->setIgnored(false);  	}  	buildPopupLists(); @@ -1166,7 +1164,7 @@ void LLFloaterPreference::resetAllIgnored()  	{  		if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)  		{ -			LLUI::sSettingGroups["ignores"]->setBOOL(iter->first, TRUE); +			iter->second->mForm->setIgnored(true);  		}  	}  } @@ -1179,7 +1177,7 @@ void LLFloaterPreference::setAllIgnored()  	{  		if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)  		{ -			LLUI::sSettingGroups["ignores"]->setBOOL(iter->first, FALSE); +			iter->second->mForm->setIgnored(false);  		}  	}  } diff --git a/indra/newview/llhints.cpp b/indra/newview/llhints.cpp index bd7fec63e8..bb8f4a995b 100644 --- a/indra/newview/llhints.cpp +++ b/indra/newview/llhints.cpp @@ -360,7 +360,7 @@ void LLHints::hideAll()  		it != end_it;  		++it)  	{ -		LLNotifications::instance().cancel(*it); +		hide(*it);  	}  } diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 951aaee705..982d82ca01 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -38,7 +38,6 @@  #include "llviewermedia.h"  #include "llviewertexture.h"  #include "llviewerwindow.h" -#include "llnotificationsutil.h"  #include "llweb.h"  #include "llrender.h"  #include "llpluginclassmedia.h" @@ -49,6 +48,12 @@  // linden library includes  #include "llfocusmgr.h"  #include "llsdutil.h" +#include "lllayoutstack.h" +#include "lliconctrl.h" +#include "lltextbox.h" +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llnotifications.h"  extern BOOL gRestoreGL; @@ -90,7 +95,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :  	mTextureWidth ( 1024 ),  	mTextureHeight ( 1024 ),  	mClearCache(false), -	mMediaID(p.media_id),  	mHomePageMimeType(p.initial_mime_type)  {  	{ @@ -177,6 +181,7 @@ void LLMediaCtrl::setTrusted( bool valIn )  //  BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )  { +	if (LLPanel::handleHover(x, y, mask)) return TRUE;  	convertInputCoords(x, y);  	if (mMediaSource) @@ -192,6 +197,7 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )  //  BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )  { +	if (LLPanel::handleScrollWheel(x, y, clicks)) return TRUE;  	if (mMediaSource && mMediaSource->hasMedia())  		mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, gKeyboard->currentMask(TRUE)); @@ -202,6 +208,7 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )  //  BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )  { +	if (LLPanel::handleMouseUp(x, y, mask)) return TRUE;  	convertInputCoords(x, y);  	if (mMediaSource) @@ -226,6 +233,7 @@ BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )  //  BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask )  { +	if (LLPanel::handleMouseDown(x, y, mask)) return TRUE;  	convertInputCoords(x, y);  	if (mMediaSource) @@ -245,6 +253,7 @@ BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask )  //  BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask )  { +	if (LLPanel::handleRightMouseUp(x, y, mask)) return TRUE;  	convertInputCoords(x, y);  	if (mMediaSource) @@ -269,6 +278,7 @@ BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask )  //  BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )  { +	if (LLPanel::handleRightMouseDown(x, y, mask)) return TRUE;  	convertInputCoords(x, y);  	if (mMediaSource) @@ -288,6 +298,7 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )  //  BOOL LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask )  { +	if (LLPanel::handleDoubleClick(x, y, mask)) return TRUE;  	convertInputCoords(x, y);  	if (mMediaSource) @@ -342,6 +353,85 @@ void LLMediaCtrl::onFocusLost()  //  BOOL LLMediaCtrl::postBuild ()  { +	LLLayoutStack::Params layout_p; +	layout_p.name = "notification_stack"; +	layout_p.rect = LLRect(0,getLocalRect().mTop,getLocalRect().mRight, 30); +	layout_p.follows.flags = FOLLOWS_ALL; +	layout_p.mouse_opaque = false; +	layout_p.orientation = "vertical"; + +	LLLayoutStack* stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p); +	addChild(stackp); + +	LLLayoutPanel::Params panel_p; +	panel_p.rect = LLRect(0, 30, 800, 0); +	panel_p.min_height = 30; +	panel_p.name = "notification_area"; +	panel_p.visible = false; +	panel_p.user_resize = false; +	panel_p.background_visible = true; +	panel_p.bg_alpha_image.name = "Yellow_Gradient"; +	panel_p.auto_resize = false; +	LLLayoutPanel* notification_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); +	stackp->addChild(notification_panel); + +	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>(); +	panel_p.auto_resize = true; +	panel_p.mouse_opaque = false; +	LLLayoutPanel* dummy_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); +	stackp->addChild(dummy_panel); + +	layout_p = LLUICtrlFactory::getDefaultParams<LLLayoutStack>(); +	layout_p.rect = LLRect(0, 30, 800, 0); +	layout_p.follows.flags = FOLLOWS_ALL; +	layout_p.orientation = "horizontal"; +	stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p); +	notification_panel->addChild(stackp); + +	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>(); +	panel_p.rect.height = 30; +	LLLayoutPanel* panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); +	stackp->addChild(panel); + +	LLIconCtrl::Params icon_p; +	icon_p.name = "notification_icon"; +	icon_p.rect = LLRect(5, 23, 21, 8); +	panel->addChild(LLUICtrlFactory::create<LLIconCtrl>(icon_p)); + +	LLTextBox::Params text_p; +	text_p.rect = LLRect(31, 20, 430, 0); +	text_p.text_color = LLColor4::black; +	text_p.font = LLFontGL::getFontSansSerif(); +	text_p.font.style = "BOLD"; +	text_p.name = "notification_text"; +	text_p.use_ellipses = true; +	panel->addChild(LLUICtrlFactory::create<LLTextBox>(text_p)); + +	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>(); +	panel_p.auto_resize = false; +	panel_p.user_resize = false; +	panel_p.name="form_elements"; +	panel_p.rect = LLRect(0, 30, 130, 0); +	LLLayoutPanel* form_elements_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); +	stackp->addChild(form_elements_panel); + +	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>(); +	panel_p.auto_resize = false; +	panel_p.user_resize = false; +	panel_p.rect = LLRect(0, 30, 25, 0); +	LLLayoutPanel* close_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); +	stackp->addChild(close_panel); + +	LLButton::Params button_p; +	button_p.name = "close_notification"; +	button_p.rect = LLRect(5, 23, 21, 7); +	button_p.image_color=LLUIColorTable::instance().getColor("DkGray_66"); +    button_p.image_unselected.name="Icon_Close_Foreground"; +	button_p.image_selected.name="Icon_Close_Press"; +	button_p.click_callback.function = boost::bind(&LLMediaCtrl::onCloseNotification, this); + +	close_panel->addChild(LLUICtrlFactory::create<LLButton>(button_p)); +  	setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2));  	return TRUE;  } @@ -350,6 +440,7 @@ BOOL LLMediaCtrl::postBuild ()  //  BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )  { +	if (LLPanel::handleKeyHere(key, mask)) return TRUE;  	BOOL result = FALSE;  	if (mMediaSource) @@ -375,6 +466,7 @@ void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility )  //  BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)  { +	if (LLPanel::handleUnicodeCharHere(uni_char)) return TRUE;  	BOOL result = FALSE;  	if (mMediaSource) @@ -837,6 +929,14 @@ void LLMediaCtrl::draw()  	if ( mBorder && mBorder->getVisible() )  		mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) ); +	if (mCurNotification) +	{ +		if (mCurNotification->isCancelled() || mCurNotification->isExpired()) +		{ +			hideNotification(); +		} +	} +  	LLPanel::draw(); @@ -941,13 +1041,16 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)  			std::string url = self->getClickURL();  			std::string target = self->getClickTarget();  			std::string uuid = self->getClickUUID(); -			 +  			if(gSavedSettings.getBOOL("MediaEnablePopups"))  			{ -				LLNotificationsUtil::add("PopupAttempt",  + +				LLNotificationPtr popup_notify = LLNotificationsUtil::add("PopupAttempt",   					LLSD(),   					LLSD().with("source", mMediaID).with("target", target).with("url", url).with("uuid", uuid),  					boost::bind(&LLMediaCtrl::onPopup, this, _1, _2)); +				showNotification(popup_notify); +				break;  			}  		}; @@ -1018,3 +1121,100 @@ void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response)  	}  } + +void LLMediaCtrl::onCloseNotification() +{ +	LLNotifications::instance().cancel(mCurNotification); +} + +void LLMediaCtrl::onClickIgnore(LLUICtrl* ctrl) +{ +	bool check = ctrl->getValue().asBoolean(); +	if (mCurNotification && mCurNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN) +	{ +		// question was "show again" so invert value to get "ignore" +		check = !check; +	} +	mCurNotification->setIgnored(check); +} + +void LLMediaCtrl::onClickNotificationButton(const std::string& name) +{ +	if (!mCurNotification) return; + +	LLSD response = mCurNotification->getResponseTemplate(); +	response[name] = true; + +	mCurNotification->respond(response);  +} + +void LLMediaCtrl::showNotification(LLNotificationPtr notify) +{ +	mCurNotification = notify; + +	// add popup here +	LLSD payload = notify->getPayload(); + +	LLNotificationFormPtr formp = notify->getForm(); +	LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area"); +	panel.setVisible(true); +	panel.getChild<LLUICtrl>("notification_icon")->setValue(notify->getIcon()); +	panel.getChild<LLUICtrl>("notification_text")->setValue(notify->getMessage()); +	panel.getChild<LLUICtrl>("notification_text")->setToolTip(notify->getMessage()); +	LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType();  +	LLLayoutPanel& form_elements = panel.getChildRef<LLLayoutPanel>("form_elements"); +	form_elements.deleteAllChildren(); + +	const S32 FORM_PADDING_HORIZONTAL = 10; +	const S32 FORM_PADDING_VERTICAL = 3; +	S32 cur_x = FORM_PADDING_HORIZONTAL; + +	if (ignore_type != LLNotificationForm::IGNORE_NO) +	{ +		LLCheckBoxCtrl::Params checkbox_p; +		checkbox_p.name = "ignore_check"; +		checkbox_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL); +		checkbox_p.label = formp->getIgnoreMessage(); +		checkbox_p.label_text.text_color = LLColor4::black; +		checkbox_p.commit_callback.function = boost::bind(&LLMediaCtrl::onClickIgnore, this, _1); +		checkbox_p.initial_value = formp->getIgnored(); + +		LLCheckBoxCtrl* check = LLUICtrlFactory::create<LLCheckBoxCtrl>(checkbox_p); +		check->setRect(check->getBoundingRect()); +		form_elements.addChild(check); +		cur_x = check->getRect().mRight + FORM_PADDING_HORIZONTAL; +	} + +	for (S32 i = 0; i < formp->getNumElements(); i++) +	{ +		LLSD form_element = formp->getElement(i); +		if (form_element["type"].asString() == "button") +		{ +			LLButton::Params button_p; +			button_p.name = form_element["name"]; +			button_p.label = form_element["text"]; +			button_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL); +			button_p.click_callback.function = boost::bind(&LLMediaCtrl::onClickNotificationButton, this, form_element["name"].asString()); +			button_p.auto_resize = true; + +			LLButton* button = LLUICtrlFactory::create<LLButton>(button_p); +			button->autoResize(); +			form_elements.addChild(button); + +			cur_x = button->getRect().mRight + FORM_PADDING_HORIZONTAL; +		} +	} + + +	form_elements.reshape(cur_x, form_elements.getRect().getHeight()); + +	//LLWeb::loadURL(payload["url"], payload["target"]); +} + +void LLMediaCtrl::hideNotification() +{ +	LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area"); +	panel.setVisible(FALSE); + +	mCurNotification.reset(); +} diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 54d50ce4d0..b8e10d5591 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -108,7 +108,7 @@ public:  		void setHomePageUrl( const std::string& urlIn, const std::string& mime_type = LLStringUtil::null );  		std::string getHomePageUrl(); -		 +  		void setTarget(const std::string& target);  		// set/clear URL to visit when a 404 page is reached @@ -142,8 +142,9 @@ public:  		bool getDecoupleTextureSize() { return mDecoupleTextureSize; }  		void setTextureSize(S32 width, S32 height); -		void setMediaID(const std::string& id) { mMediaID = id; } +		void showNotification(boost::shared_ptr<class LLNotification> notify); +		void hideNotification();  		// over-rides  		virtual BOOL handleKeyHere( KEY key, MASK mask); @@ -166,6 +167,9 @@ public:  	private:  		void onVisibilityChange ( const LLSD& new_visibility );  		void onPopup(const LLSD& notification, const LLSD& response); +		void onCloseNotification(); +		void onClickNotificationButton(const std::string& name); +		void onClickIgnore(LLUICtrl* ctrl);  		const S32 mTextureDepthBytes;  		LLUUID mMediaTextureID; @@ -188,8 +192,8 @@ public:  		bool mDecoupleTextureSize;  		S32 mTextureWidth;  		S32 mTextureHeight; -		std::string mMediaID;  		bool mClearCache; +		boost::shared_ptr<class LLNotification> mCurNotification;  };  #endif // LL_LLMediaCtrl_H diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml index c220124f46..1cb8613eb4 100644 --- a/indra/newview/skins/default/xui/en/floater_media_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml @@ -200,76 +200,6 @@               name="browser"               top="0"               width="540" /> -          <layout_stack  -            name="notification_stack" -            left="0" -            top="0" -            width="540" -            bottom="-30" -            follows="all" -            mouse_opaque="false" -            orientation="vertical"> -            <layout_panel -              height="30" -              min_height="30"  -              layout="topleft" -              name="notification_area" -              visible="false" -              user_resize="false" -              background_visible="true" -              bg_alpha_image="Yellow_Gradient" -              auto_resize="false" -              width="800"> -              <layout_stack -                top="0" -                height="30" -                width="800" -                left="0" -                follows="bottom|left|right" -                orientation="horizontal"> -                <layout_panel -                  height="30"> -                  <icon name="notification_icon" -                        left="5" -                        top="7" -                        width="16" -                        height="15"/> -                  <text left_pad="8" -                        top="10" -                        height="25" -                        width="400" -                        text_color="black" -                        font="SansSerifSmall" -                        font.style="BOLD" -                        name="notification_text" -                        value="Notification text here"/> -                </layout_panel> -                <layout_panel -                  height="30" -                  width="130" -                  auto_resize="false" -                  user_resize="false" -                  name="form_elements"/> -                <layout_panel -                  height="30" -                  width="25" -                  auto_resize="false" -                  name="close_panel"> -                  <button left="5" -                          name="close_notification" -                          width="16" -                          height="16" -                          top="8" -                          image_color="DkGray_66" -                          image_unselected="Icon_Close_Foreground" -                          image_selected="Icon_Close_Press"/> -                </layout_panel> -              </layout_stack> -            </layout_panel> -            <layout_panel -              mouse_opaque="false"  -              auto_resize="true"/> -          </layout_stack>              <button               follows="bottom|left"               height="20" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 59fcd3513e..9d947480b3 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2059,7 +2059,8 @@ Would you be my friend?   icon="alertmodal.tga"   label="Save Outfit"   name="SaveOutfitAs" - type="alertmodal"> + type="alertmodal" + unique="true">      Save what I'm wearing as a new Outfit:      <form name="form">        <input name="message" type="text"> @@ -2075,7 +2076,6 @@ Would you be my friend?         name="Cancel"         text="Cancel"/>      </form> -    <unique/>    </notification>    <notification @@ -4010,37 +4010,37 @@ Go to your [http://secondlife.com/account/ Dashboard] to see your account histor    <notification     icon="alertmodal.tga"     name="ConfirmQuit" -   type="alertmodal"> +   type="alertmodal" +   unique="true">  Are you sure you want to quit?      <usetemplate       ignoretext="Confirm before I quit"       name="okcancelignore"       notext="Don't Quit"       yestext="Quit"/> -     <unique/>    </notification>    <notification     icon="alertmodal.tga"     name="DeleteItems" -   type="alertmodal"> +   type="alertmodal" +   unique="true">      [QUESTION]      <usetemplate       ignoretext="Confirm before deleting items"       name="okcancelignore"       notext="Cancel"       yestext="OK"/> -    <unique/>    </notification>    <notification     icon="alertmodal.tga"     name="HelpReportAbuseEmailLL" -   type="alert"> +   type="alert" +   unique="true">  Use this tool to report violations of the [http://secondlife.com/corporate/tos.php Terms of Service] and [http://secondlife.com/corporate/cs.php Community Standards].  All reported abuses are investigated and resolved. -   <unique/>    </notification>    <notification @@ -4982,47 +4982,47 @@ Message from [NAME]:     icon="notify.tga"     name="NotSafe"     persist="true" -   type="notify"> +   type="notify" +   unique="true">  This land has damage enabled.  You can be hurt here. If you die, you will be teleported to your home location. -    <unique/>    </notification>    <notification     icon="notify.tga"     name="NoFly"     persist="true" -   type="notify"> +   type="notify" +   unique="true">  This area has flying disabled.  You can't fly here. -    <unique/>    </notification>    <notification     icon="notify.tga"     name="PushRestricted"     persist="true" -   type="notify"> +   type="notify" +   unique="true">  This area does not allow pushing. You can't push others here unless you own the land. -    <unique/>    </notification>    <notification     icon="notify.tga"     name="NoVoice"     persist="true" -   type="notify"> +   type="notify" +   unique="true">  This area has voice chat disabled. You won't be able to hear anyone talking. -    <unique/>    </notification>    <notification     icon="notify.tga"     name="NoBuild"     persist="true" -   type="notify"> +   type="notify" +   unique="true">  This area has building disabled. You can't build or rez objects here. -    <unique/>    </notification>    <notification @@ -5943,9 +5943,9 @@ The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum    <notification     icon="notifytip.tga"     name="ProximalVoiceChannelFull" -   type="notifytip"> +   type="notifytip" +   unique="true">  We're sorry.  This area has reached maximum capacity for voice conversations.  Please try to use voice in another area. -    <unique/>    </notification>    <notification @@ -6002,9 +6002,9 @@ Failed to connect to [VOICE_CHANNEL_NAME], please try again later.  You will now     duration="10"     icon="notifytip.tga"     name="VoiceLoginRetry" -   type="notifytip"> +   type="notifytip" +   unique="true">  We are creating a voice channel for you. This may take up to one minute. -    <unique/>    </notification>    <notification @@ -6012,10 +6012,10 @@ We are creating a voice channel for you. This may take up to one minute.     name="VoiceEffectsExpired"     sound="UISndAlert"     persist="true" -   type="notify"> +   type="notify" +   unique="true">  One or more of your subscribed Voice Morphs has expired.  [[URL] Click here] to renew your subscription. -    <unique/>    </notification>    <notification @@ -6023,10 +6023,10 @@ One or more of your subscribed Voice Morphs has expired.     name="VoiceEffectsExpiredInUse"     sound="UISndAlert"     persist="true" -   type="notify"> +   type="notify" +   unique="true">  The active Voice Morph has expired, your normal voice settings have been applied.  [[URL] Click here] to renew your subscription. -    <unique/>    </notification>    <notification @@ -6034,10 +6034,10 @@ The active Voice Morph has expired, your normal voice settings have been applied     name="VoiceEffectsWillExpire"     sound="UISndAlert"     persist="true" -   type="notify"> +   type="notify" +   unique="true">  One or more of your Voice Morphs will expire in less than [INTERVAL] days.  [[URL] Click here] to renew your subscription. -    <unique/>    </notification>    <notification @@ -6045,9 +6045,9 @@ One or more of your Voice Morphs will expire in less than [INTERVAL] days.     name="VoiceEffectsNew"     sound="UISndAlert"     persist="true" -   type="notify"> +   type="notify" +   unique="true">  New Voice Morphs are available! -    <unique/>    </notification>    <notification @@ -6374,8 +6374,8 @@ Are you sure you want to leave this call?       ignoretext="Confirm before I leave call"       name="okcancelignore"       notext="No" -     yestext="Yes"/> -    <unique/> +     yestext="Yes" +     unique="true"/>    </notification>    <notification @@ -6391,64 +6391,64 @@ Mute everyone?       ignoretext="Confirm before I mute all participants in a group call"       name="okcancelignore"       yestext="Ok" -     notext="Cancel"/> -    <unique/> +     notext="Cancel" +     unique="true"/>    </notification>    <notification    name="HintChat"    label="Chat" -  type="hint"> +  type="hint" +  unique="true">      To join the conversation, type into the chat field below. -    <unique/>    </notification>    <notification    name="HintSit"    label="Stand" -  type="hint"> +  type="hint" +  unique="true">      To stand up and exit the sitting position, click the Stand button. -    <unique/>    </notification>    <notification    name="HintDestinationGuide"    label="Explore the World" -  type="hint"> +  type="hint" +  unique="true">      The Destination Guide contains thousands of new places to discover. Select a location and choose Teleport to start exploring. -    <unique/>    </notification>    <notification      name="HintSidePanel"      label="Side Panel" -    type="hint"> +    type="hint" +    unique="true">      Get quick access to your inventory, outfits, profiles and more in the side panel. -    <unique/>    </notification>    <notification    name="HintMove"    label="Move" -  type="hint"> +  type="hint" +  unique="true">      To walk or run, open the Move Panel and use the directional arrows to navigate. You can also use the directional keys on your keyboard. -    <unique/>    </notification>    <notification    name="HintInventory"    label="Inventory" -  type="hint"> +  type="hint" +  unique="true">      Check your inventory to find items. Newest items can be easily found in the Recent tab. -    <unique/>    </notification>    <notification    name="HintLindenDollar"    label="You've got Linden Dollars!" -  type="hint"> +  type="hint" +  unique="true">      Here's your current balance of L$. Click Buy L$ to purchase more Linden Dollars. -    <unique/>    </notification>    <notification @@ -6456,19 +6456,17 @@ Mute everyone?    icon="Popup_Caution"    type="browser"    duration="10" -  > +  unique="true">      A pop-up was prevented from opening. -    <unique/>      <form name="form">        <ignore name="ignore" -       text="Enable all pop-ups"/> +              control="MediaEnablePopups"  +              text="Enable all pop-ups"/>        <button default="true"                index="0"                name="open"                text="Open pop-up window"/>      </form> - -    </notification> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index 2c6ceeef2e..879781f746 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -320,7 +320,19 @@      radio_style="false"      width="400"      top_pad="5"/> - +  <check_box +    top_delta="4" +    enabled="true" +    follows="left|top" +    height="14" +    initial_value="false" +    control_name="MediaEnablePopups" +    label="Enable media browser pop-ups" +    left_delta="0" +    mouse_opaque="true" +    name="media_popup_enabled" +    width="400"            +    top_pad="5"/>    <check_box      top_delta="4"      enabled="true"  | 
