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