summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llui/llnotifications.cpp91
-rw-r--r--indra/llui/llnotifications.h55
-rw-r--r--indra/llui/llnotificationslistener.cpp7
-rw-r--r--indra/llui/llnotificationtemplate.h10
-rw-r--r--indra/llxuixml/llinitparam.cpp2
-rw-r--r--indra/llxuixml/llinitparam.h18
-rw-r--r--indra/newview/llbrowsernotification.cpp18
-rw-r--r--indra/newview/llfloatermediabrowser.cpp109
-rw-r--r--indra/newview/llfloatermediabrowser.h6
-rw-r--r--indra/newview/llfloaterpreference.cpp10
-rw-r--r--indra/newview/llhints.cpp2
-rw-r--r--indra/newview/llmediactrl.cpp208
-rw-r--r--indra/newview/llmediactrl.h10
-rw-r--r--indra/newview/skins/default/xui/en/floater_media_browser.xml70
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml104
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_setup.xml14
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&apos;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&apos;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&apos;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&apos;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&apos;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&apos;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"