diff options
author | Richard Linden <none@none> | 2010-09-16 00:45:27 -0700 |
---|---|---|
committer | Richard Linden <none@none> | 2010-09-16 00:45:27 -0700 |
commit | 387011a1ff519d0e339b446ff5d02f0d009b7e5d (patch) | |
tree | 4bf7a49fa856a0bd067071386f12553e6aa886f2 | |
parent | 0336487e34425c1630cd84da45dc64bc7c7c03be (diff) |
EXP-29 WIP Implement popup blocking
added web popup notification overlay
-rw-r--r-- | indra/newview/llbrowsernotification.cpp | 57 | ||||
-rw-r--r-- | indra/newview/llfloatermediabrowser.cpp | 100 | ||||
-rw-r--r-- | indra/newview/llfloatermediabrowser.h | 8 | ||||
-rw-r--r-- | indra/newview/llmediactrl.cpp | 36 | ||||
-rw-r--r-- | indra/newview/llmediactrl.h | 4 | ||||
-rw-r--r-- | indra/newview/llnotificationhandler.h | 9 | ||||
-rw-r--r-- | indra/newview/llnotificationmanager.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llviewermedia.cpp | 18 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_media_browser.xml | 146 |
9 files changed, 287 insertions, 93 deletions
diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp new file mode 100644 index 0000000000..e162527e23 --- /dev/null +++ b/indra/newview/llbrowsernotification.cpp @@ -0,0 +1,57 @@ +/** + * @file llbrowsernotification.cpp + * @brief Notification Handler Class for browser popups + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "llnotificationhandler.h" +#include "llnotifications.h" +#include "llfloatermediabrowser.h" +#include "llfloaterreg.h" + +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(); + } + } + return false; +} diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp index 5d0df1f037..ba8128e902 100644 --- a/indra/newview/llfloatermediabrowser.cpp +++ b/indra/newview/llfloatermediabrowser.cpp @@ -45,7 +45,10 @@ #include "llviewermedia.h" #include "llviewerparcelmedia.h" #include "llcombobox.h" +#include "lllayoutstack.h" +#include "llcheckboxctrl.h" +#include "llnotifications.h" // TEMP #include "llsdutil.h" @@ -141,12 +144,16 @@ 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); @@ -243,6 +250,73 @@ 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) { @@ -374,3 +448,29 @@ void LLFloaterMediaBrowser::openMedia(const std::string& media_url) mBrowser->navigateTo(media_url); 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 ee4aef814f..e6511c6e85 100644 --- a/indra/newview/llfloatermediabrowser.h +++ b/indra/newview/llfloatermediabrowser.h @@ -33,6 +33,7 @@ class LLComboBox; class LLMediaCtrl; +class LLNotification; class LLFloaterMediaBrowser : public LLFloater, @@ -55,6 +56,8 @@ 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); @@ -70,9 +73,14 @@ 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; + boost::shared_ptr<LLNotification> mCurNotification; }; #endif // LL_LLFLOATERMEDIABROWSER_H diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 1de249a3c1..16519bc0d5 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -48,6 +48,7 @@ // linden library includes #include "llfocusmgr.h" +#include "llsdutil.h" extern BOOL gRestoreGL; @@ -62,7 +63,8 @@ LLMediaCtrl::Params::Params() texture_width("texture_width", 1024), texture_height("texture_height", 1024), caret_color("caret_color"), - initial_mime_type("initial_mime_type") + initial_mime_type("initial_mime_type"), + media_id("media_id") { tab_stop(false); } @@ -88,6 +90,7 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : mTextureWidth ( 1024 ), mTextureHeight ( 1024 ), mClearCache(false), + mMediaID(p.media_id), mHomePageMimeType(p.initial_mime_type) { { @@ -924,9 +927,29 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) case MEDIA_EVENT_CLICK_LINK_HREF: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL; + // retrieve the event parameters + std::string url = self->getClickURL(); + std::string target = self->getClickTarget(); + U32 target_type = self->getClickTargetType(); + + switch (target_type) + { + case LLPluginClassMedia::TARGET_NONE: + // ignore this click and let media plugin handle it + break; + default: + if(gSavedSettings.getBOOL("MediaEnablePopups")) + { + + LLNotificationsUtil::add("PopupAttempt", + LLSD(), + LLSD().with("source", mMediaID).with("target", target).with("url", url), + boost::bind(&LLMediaCtrl::onPopup, this, _1, _2)); + } + break; + } }; - break; - + case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; @@ -975,3 +998,10 @@ std::string LLMediaCtrl::getCurrentNavUrl() return mCurrentNavUrl; } +void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response) +{ + if (response["open"]) + { + LLWeb::loadURL(notification["payload"]["url"], notification["payload"]["target"]); + } +} diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 755d1e1b04..3ba2904003 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -59,6 +59,7 @@ public: Optional<LLUIColor> caret_color; Optional<std::string> initial_mime_type; + Optional<std::string> media_id; Params(); }; @@ -139,6 +140,7 @@ public: bool getDecoupleTextureSize() { return mDecoupleTextureSize; } void setTextureSize(S32 width, S32 height); + void setMediaID(const std::string& id) { mMediaID = id; } // over-rides @@ -161,6 +163,7 @@ public: private: void onVisibilityChange ( const LLSD& new_visibility ); + void onPopup(const LLSD& notification, const LLSD& response); const S32 mTextureDepthBytes; LLUUID mMediaTextureID; @@ -182,6 +185,7 @@ public: bool mDecoupleTextureSize; S32 mTextureWidth; S32 mTextureHeight; + std::string mMediaID; bool mClearCache; }; diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 3c84a02b68..28a69f2373 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -276,6 +276,15 @@ public: virtual bool processNotification(const LLSD& notify); }; +/** + * Handler for browser notifications + */ +class LLBrowserNotification : public LLSingleton<LLBrowserNotification> +{ +public: + virtual bool processNotification(const LLSD& notify); + +}; class LLHandlerUtil { diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp index 17cf1ab2b8..6988227128 100644 --- a/indra/newview/llnotificationmanager.cpp +++ b/indra/newview/llnotificationmanager.cpp @@ -61,6 +61,7 @@ void LLNotificationManager::init() LLNotificationChannel::buildChannel("IM Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytoast")); LLNotificationChannel::buildChannel("Offer", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "offer")); LLNotificationChannel::buildChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint")); + LLNotificationChannel::buildChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser")); LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); @@ -70,6 +71,7 @@ void LLNotificationManager::init() LLNotifications::instance().getChannel("IM Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); LLNotifications::instance().getChannel("Offer")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); LLNotifications::instance().getChannel("Hints")->connectChanged(boost::bind(&LLHintHandler::processNotification, LLHintHandler::getInstance(), _1)); + LLNotifications::instance().getChannel("Browser")->connectChanged(boost::bind(&LLBrowserNotification::processNotification, LLBrowserNotification::getInstance(), _1)); mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD())); mNotifyHandlers["notifytip"] = boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD())); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 012a4d2920..31e4753553 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -2819,24 +2819,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla case MEDIA_EVENT_CLICK_LINK_HREF: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << plugin->getClickTarget() << "\", uri is " << plugin->getClickURL() << LL_ENDL; - // retrieve the event parameters - std::string url = plugin->getClickURL(); - std::string target = plugin->getClickTarget(); - U32 target_type = plugin->getClickTargetType(); - - switch (target_type) - { - case LLPluginClassMedia::TARGET_NONE: - // ignore this click and let media plugin handle it - break; - default: - if(gSavedSettings.getBOOL("MediaEnablePopups")) - { - // loadURL now handles distinguishing between _blank, _external, and other named targets. - LLWeb::loadURL(url, target); - } - break; - } }; break; case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: 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 3b78da2a79..c220124f46 100644 --- a/indra/newview/skins/default/xui/en/floater_media_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml @@ -31,6 +31,7 @@ width="800"> <layout_panel auto_resize="false" + default_tab_group="1" height="20" layout="topleft" left="0" @@ -78,6 +79,7 @@ <combo_box allow_text_entry="true" follows="left|top|right" + tab_group="1" height="20" layout="topleft" left_pad="5" @@ -182,76 +184,6 @@ function="MediaBrowser.Assign" /> </button> </layout_panel> - <layout_panel - 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="all" - orientation="horizontal" - > - <layout_panel - height="30"> - <icon value="Popup_Caution" - 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="270" - auto_resize="false" - name="form_elements"> - <check_box name="enable_check" - left="5" - top="5" - height="20" - width="120" - label="Enable all popups" - text_enabled_color="black" - /> - <button left_pad="5" - width="140" - top="4" - label="Open pop-up window"/> - </layout_panel> - <layout_panel - height="30" - width="25" - auto_resize="false" - name="close_panel"> - <button left="5" - name="close" - 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 height="40" layout="topleft" @@ -260,14 +192,84 @@ top_delta="0" user_resize="false" width="540"> - <web_browser + <web_browser bottom="-30" - follows="left|right|top|bottom" + follows="all" layout="topleft" left="0" 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" |