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" |