diff options
Diffstat (limited to 'indra/newview')
29 files changed, 1203 insertions, 232 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 2dd32b7aa4..3862ae5731 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -222,6 +222,7 @@ set(viewer_SOURCE_FILES      llfloaterurlentry.cpp      llfloatervoiceeffect.cpp      llfloaterwater.cpp +    llfloaterwebcontent.cpp      llfloaterwhitelistentry.cpp      llfloaterwindlight.cpp      llfloaterwindowsize.cpp @@ -757,6 +758,7 @@ set(viewer_HEADER_FILES      llfloaterurlentry.h      llfloatervoiceeffect.h      llfloaterwater.h +    llfloaterwebcontent.h      llfloaterwhitelistentry.h      llfloaterwindlight.h      llfloaterwindowsize.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 06992d2b52..199ee6822f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -686,6 +686,39 @@        <key>Value</key>        <string>http://www.secondlife.com</string>      </map> +    <key>BrowserIgnoreSSLCertErrors</key> +    <map> +      <key>Comment</key> +      <string>FOR TESTING ONLY: Tell the built-in web browser to ignore SSL cert errors.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>BrowserUseDefaultCAFile</key> +    <map> +      <key>Comment</key> +      <string>Tell the built-in web browser to use the CA.pem file shipped with the client.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map> +    <key>BrowserCAFilePath</key> +    <map> +      <key>Comment</key> +      <string>Tell the built-in web browser the path to an alternative CA.pem file (only used if BrowserUseDefaultCAFile is false).</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string></string> +    </map>        <key>BlockAvatarAppearanceMessages</key>          <map>          <key>Comment</key> @@ -6572,7 +6605,18 @@      <key>MediaBrowserWindowLimit</key>      <map>        <key>Comment</key> -      <string>Maximum number of media brower windows that can be open at once (0 for no limit)</string> +      <string>Maximum number of media brower windows that can be open at once in the media browser floater (0 for no limit)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>5</integer> +    </map> +    <key>WebContentWindowLimit</key> +    <map> +      <key>Comment</key> +      <string>Maximum number of web brower windows that can be open at once in the Web content floater (0 for no limit)</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp index d6a813d608..6e77d1e336 100644 --- a/indra/newview/llbrowsernotification.cpp +++ b/indra/newview/llbrowsernotification.cpp @@ -29,8 +29,9 @@  #include "llnotificationhandler.h"  #include "llnotifications.h" -#include "llfloaterreg.h"  #include "llmediactrl.h" +#include "llviewermedia.h" +#include "llviewermediafocus.h"  using namespace LLNotificationsUI; @@ -39,10 +40,19 @@ bool LLBrowserNotification::processNotification(const LLSD& notify)  	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());  	if (!notification) return false; -	LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(notification->getPayload()["media_id"].asUUID()); +	LLUUID media_id = notification->getPayload()["media_id"].asUUID(); +	LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id);  	if (media_instance)  	{  		media_instance->showNotification(notification);  	} +	else if (LLViewerMediaFocus::instance().getControlsMediaID() == media_id) +	{ +		LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(media_id); +		if (impl) +		{ +			impl->showNotification(notification); +		} +	}  	return false;  } diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 6e778de2d8..c98bcbda45 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -586,7 +586,7 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p)  	LLLayoutStack::Params layout_p;  	layout_p.rect = stack_rect;  	layout_p.follows.flags = FOLLOWS_ALL; -	layout_p.orientation = "vertical"; +	layout_p.orientation = LLLayoutStack::VERTICAL;  	layout_p.mouse_opaque = false;  	LLLayoutStack* stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p, this); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 8ae3ccbae3..2873bc0059 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -272,7 +272,7 @@ LLSD LLFloaterAbout::getInfo()  	}  	// TODO: Implement media plugin version query -	info["QT_WEBKIT_VERSION"] = "4.6 (version number hard-coded)"; +	info["QT_WEBKIT_VERSION"] = "4.7.1 (version number hard-coded)";  	if (gPacketsIn > 0)  	{ diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp index cec98e9992..a650886d89 100644 --- a/indra/newview/llfloaterhelpbrowser.cpp +++ b/indra/newview/llfloaterhelpbrowser.cpp @@ -132,9 +132,10 @@ void LLFloaterHelpBrowser::onClickOpenWebBrowser(void* user_data)  void LLFloaterHelpBrowser::openMedia(const std::string& media_url)  { -	mBrowser->setHomePageUrl(media_url); -	//mBrowser->navigateTo("data:text/html;charset=utf-8,I'd really love to be going to:<br><b>" + media_url + "</b>"); // tofu HACK for debugging =:) -	mBrowser->navigateTo(media_url); +	// explicitly make the media mime type for this floater since it will +	// only ever display one type of content (Web). +	mBrowser->setHomePageUrl(media_url, "text/html"); +	mBrowser->navigateTo(media_url, "text/html");  	setCurrentURL(media_url);  } diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp index d20092e344..7a670dd90c 100644 --- a/indra/newview/llfloatermediabrowser.cpp +++ b/indra/newview/llfloatermediabrowser.cpp @@ -306,17 +306,14 @@ void LLFloaterMediaBrowser::setCurrentURL(const std::string& url)  {  	mCurrentURL = url; -	// redirects will navigate momentarily to about:blank, don't add to history -	if (mCurrentURL != "about:blank") -	{ -		mAddressCombo->remove(mCurrentURL); -		mAddressCombo->add(mCurrentURL); -		mAddressCombo->selectByValue(mCurrentURL); +	mAddressCombo->remove(mCurrentURL); +	mAddressCombo->add(mCurrentURL); +	mAddressCombo->selectByValue(mCurrentURL); + +	// Serialize url history +	LLURLHistory::removeURL("browser", mCurrentURL); +	LLURLHistory::addURL("browser", mCurrentURL); -		// Serialize url history -		LLURLHistory::removeURL("browser", mCurrentURL); -		LLURLHistory::addURL("browser", mCurrentURL); -	}  	getChildView("back")->setEnabled(mBrowser->canNavigateBack());  	getChildView("forward")->setEnabled(mBrowser->canNavigateForward());  	getChildView("reload")->setEnabled(TRUE); @@ -334,8 +331,15 @@ void LLFloaterMediaBrowser::onClickRefresh(void* user_data)  {  	LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; -	self->mAddressCombo->remove(0); -	self->mBrowser->navigateTo(self->mCurrentURL); +	if( self->mBrowser->getMediaPlugin() &&  self->mBrowser->getMediaPlugin()->pluginSupportsMediaBrowser()) +	{ +		bool ignore_cache = true; +		self->mBrowser->getMediaPlugin()->browse_reload( ignore_cache ); +	} +	else +	{ +		self->mBrowser->navigateTo(self->mCurrentURL); +	}  }  //static  diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index 3ed4aec89a..2041fac8d8 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -200,5 +200,5 @@ void LLFloaterSearch::search(const LLSD &key)  	url = LLWeb::expandURLSubstitutions(url, subs);  	// and load the URL in the web view -	mBrowser->navigateTo(url); +	mBrowser->navigateTo(url, "text/html");  } diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp new file mode 100644 index 0000000000..14bd5baba1 --- /dev/null +++ b/indra/newview/llfloaterwebcontent.cpp @@ -0,0 +1,402 @@ +/**
 + * @file llfloaterwebcontent.cpp
 + * @brief floater for displaying web content - e.g. profiles and search (eventually)
 + *
 + * $LicenseInfo:firstyear=2006&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"
 +
 +#include "llcombobox.h"
 +#include "lliconctrl.h"
 +#include "llfloaterreg.h"
 +#include "lllayoutstack.h"
 +#include "llpluginclassmedia.h"
 +#include "llprogressbar.h"
 +#include "lltextbox.h"
 +#include "llurlhistory.h"
 +#include "llviewercontrol.h"
 +#include "llweb.h"
 +#include "llwindow.h"
 +
 +#include "llfloaterwebcontent.h"
 +
 +LLFloaterWebContent::LLFloaterWebContent( const LLSD& key )
 +	: LLFloater( key )
 +{
 +	mCommitCallbackRegistrar.add( "WebContent.Back", boost::bind( &LLFloaterWebContent::onClickBack, this ));
 +	mCommitCallbackRegistrar.add( "WebContent.Forward", boost::bind( &LLFloaterWebContent::onClickForward, this ));
 +	mCommitCallbackRegistrar.add( "WebContent.Reload", boost::bind( &LLFloaterWebContent::onClickReload, this ));
 +	mCommitCallbackRegistrar.add( "WebContent.Stop", boost::bind( &LLFloaterWebContent::onClickStop, this ));
 +	mCommitCallbackRegistrar.add( "WebContent.EnterAddress", boost::bind( &LLFloaterWebContent::onEnterAddress, this ));
 +	mCommitCallbackRegistrar.add( "WebContent.PopExternal", boost::bind( &LLFloaterWebContent::onPopExternal, this ));
 +}
 +
 +BOOL LLFloaterWebContent::postBuild()
 +{
 +	// these are used in a bunch of places so cache them
 +	mWebBrowser = getChild< LLMediaCtrl >( "webbrowser" );
 +	mAddressCombo = getChild< LLComboBox >( "address" );
 +	mStatusBarText = getChild< LLTextBox >( "statusbartext" );
 +	mStatusBarProgress = getChild<LLProgressBar>("statusbarprogress" );
 +
 +	// observe browser events
 +	mWebBrowser->addObserver( this );
 +
 +	// these buttons are always enabled
 +	getChildView("reload")->setEnabled( true );
 +	getChildView("popexternal")->setEnabled( true );
 +
 +	// cache image for secure browsing
 +	mSecureLockIcon = getChild< LLIconCtrl >("media_secure_lock_flag");
 +
 +	// initialize the URL history using the system URL History manager
 +	initializeURLHistory();
 +
 +	return TRUE;
 +}
 +
 +void LLFloaterWebContent::initializeURLHistory()
 +{
 +	// start with an empty list
 +	LLCtrlListInterface* url_list = childGetListInterface("address");
 +	if (url_list)
 +	{
 +		url_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
 +	}
 +
 +	// Get all of the entries in the "browser" collection
 +	LLSD browser_history = LLURLHistory::getURLHistory("browser");
 +	LLSD::array_iterator iter_history =
 +		browser_history.beginArray();
 +	LLSD::array_iterator end_history =
 +		browser_history.endArray();
 +	for(; iter_history != end_history; ++iter_history)
 +	{
 +		std::string url = (*iter_history).asString();
 +		if(! url.empty())
 +			url_list->addSimpleElement(url);
 +	}
 +}
 +
 +//static
 +void LLFloaterWebContent::create( const std::string &url, const std::string& target, const std::string& uuid )
 +{
 +	lldebugs << "url = " << url << ", target = " << target << ", uuid = " << uuid << llendl;
 +
 +	std::string tag = target;
 +
 +	if(target.empty() || target == "_blank")
 +	{
 +		if(!uuid.empty())
 +		{
 +			tag = uuid;
 +		}
 +		else
 +		{
 +			// create a unique tag for this instance
 +			LLUUID id;
 +			id.generate();
 +			tag = id.asString();
 +		}
 +	}
 +
 +	S32 browser_window_limit = gSavedSettings.getS32("WebContentWindowLimit");
 +
 +	if(LLFloaterReg::findInstance("web_content", tag) != NULL)
 +	{
 +		// There's already a web browser for this tag, so we won't be opening a new window.
 +	}
 +	else if(browser_window_limit != 0)
 +	{
 +		// showInstance will open a new window.  Figure out how many web browsers are already open,
 +		// and close the least recently opened one if this will put us over the limit.
 +
 +		LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList("web_content");
 +		lldebugs << "total instance count is " << instances.size() << llendl;
 +
 +		for(LLFloaterReg::const_instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); iter++)
 +		{
 +			lldebugs << "    " << (*iter)->getKey() << llendl;
 +		}
 +
 +		if(instances.size() >= (size_t)browser_window_limit)
 +		{
 +			// Destroy the least recently opened instance
 +			(*instances.begin())->closeFloater();
 +		}
 +	}
 +
 +	LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::showInstance("web_content", tag));
 +	llassert(browser);
 +	if(browser)
 +	{
 +		browser->mUUID = uuid;
 +
 +		// tell the browser instance to load the specified URL
 +		browser->open_media(url, target);
 +		LLViewerMedia::proxyWindowOpened(target, uuid);
 +	}
 +}
 +
 +//static
 +void LLFloaterWebContent::closeRequest(const std::string &uuid)
 +{
 +	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("web_content");
 +	lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl;
 +	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
 +	{
 +		LLFloaterWebContent* i = dynamic_cast<LLFloaterWebContent*>(*iter);
 +		lldebugs << "    " << i->mUUID << llendl;
 +		if (i && i->mUUID == uuid)
 +		{
 +			i->closeFloater(false);
 +			return;
 + 		}
 + 	}
 +}
 +
 +//static
 +void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height)
 +{
 +	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("web_content");
 +	lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl;
 +	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
 +	{
 +		LLFloaterWebContent* i = dynamic_cast<LLFloaterWebContent*>(*iter);
 +		lldebugs << "    " << i->mUUID << llendl;
 +		if (i && i->mUUID == uuid)
 +		{
 +			i->geometryChanged(x, y, width, height);
 +			return;
 +		}
 +	}
 +}
 +
 +void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height)
 +{
 +	// Make sure the layout of the browser control is updated, so this calculation is correct.
 +	LLLayoutStack::updateClass();
 +
 +	// TODO: need to adjust size and constrain position to make sure floaters aren't moved outside the window view, etc.
 +	LLCoordWindow window_size;
 +	getWindow()->getSize(&window_size);
 +
 +	// Adjust width and height for the size of the chrome on the web Browser window.
 +	width += getRect().getWidth() - mWebBrowser->getRect().getWidth();
 +	height += getRect().getHeight() - mWebBrowser->getRect().getHeight();
 +
 +	LLRect geom;
 +	geom.setOriginAndSize(x, window_size.mY - (y + height), width, height);
 +
 +	lldebugs << "geometry change: " << geom << llendl;
 +
 +	handleReshape(geom,false);
 +}
 +
 +void LLFloaterWebContent::open_media(const std::string& web_url, const std::string& target)
 +{
 +	// Specifying a mime type of text/html here causes the plugin system to skip the MIME type probe and just open a browser plugin.
 +	mWebBrowser->setHomePageUrl(web_url, "text/html");
 +	mWebBrowser->setTarget(target);
 +	mWebBrowser->navigateTo(web_url, "text/html");
 +	set_current_url(web_url);
 +}
 +
 +//virtual
 +void LLFloaterWebContent::onClose(bool app_quitting)
 +{
 +	LLViewerMedia::proxyWindowClosed(mUUID);
 +	destroy();
 +}
 +
 +// virtual
 +void LLFloaterWebContent::draw()
 +{
 +	// this is asychronous so we need to keep checking
 +	getChildView( "back" )->setEnabled( mWebBrowser->canNavigateBack() );
 +	getChildView( "forward" )->setEnabled( mWebBrowser->canNavigateForward() );
 +
 +	LLFloater::draw();
 +}
 +
 +// virtual
 +void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 +{
 +	if(event == MEDIA_EVENT_LOCATION_CHANGED)
 +	{
 +		const std::string url = self->getLocation();
 +
 +		if ( url.length() )
 +			mStatusBarText->setText( url );
 +
 +		set_current_url( url );
 +	}
 +	else if(event == MEDIA_EVENT_NAVIGATE_BEGIN)
 +	{
 +		// flags are sent with this event
 +		getChildView("back")->setEnabled( self->getHistoryBackAvailable() );
 +		getChildView("forward")->setEnabled( self->getHistoryForwardAvailable() );
 +
 +		// toggle visibility of these buttons based on browser state
 +		getChildView("reload")->setVisible( false );
 +		getChildView("stop")->setVisible( true );
 +
 +		// turn "on" progress bar now we're about to start loading
 +		mStatusBarProgress->setVisible( true );
 +	}
 +	else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
 +	{
 +		// flags are sent with this event
 +		getChildView("back")->setEnabled( self->getHistoryBackAvailable() );
 +		getChildView("forward")->setEnabled( self->getHistoryForwardAvailable() );
 +
 +		// toggle visibility of these buttons based on browser state
 +		getChildView("reload")->setVisible( true );
 +		getChildView("stop")->setVisible( false );
 +
 +		// turn "off" progress bar now we're loaded
 +		mStatusBarProgress->setVisible( false );
 +
 +		// we populate the status bar with URLs as they change so clear it now we're done
 +		const std::string end_str = "";
 +		mStatusBarText->setText( end_str );
 +
 +		// decide if secure browsing icon should be displayed
 +		std::string prefix =  std::string("https://");
 +		std::string test_prefix = mCurrentURL.substr(0, prefix.length());
 +		LLStringUtil::toLower(test_prefix);
 +		if(test_prefix == prefix)
 +		{
 +			mSecureLockIcon->setVisible(true);
 +		}
 +		else
 +		{
 +			mSecureLockIcon->setVisible(false);
 +		}
 +	}
 +	else if(event == MEDIA_EVENT_CLOSE_REQUEST)
 +	{
 +		// The browser instance wants its window closed.
 +		closeFloater();
 +	}
 +	else if(event == MEDIA_EVENT_GEOMETRY_CHANGE)
 +	{
 +		geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight());
 +	}
 +	else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED )
 +	{
 +		const std::string text = self->getStatusText();
 +		if ( text.length() )
 +			mStatusBarText->setText( text );
 +	}
 +	else if(event == MEDIA_EVENT_PROGRESS_UPDATED )
 +	{
 +		int percent = (int)self->getProgressPercent();
 +		mStatusBarProgress->setPercent( percent );
 +	}
 +	else if(event == MEDIA_EVENT_NAME_CHANGED )
 +	{
 +		std::string page_title = self->getMediaName();
 +		// simulate browser behavior - title is empty, use the current URL
 +		if ( page_title.length() > 0 )
 +			setTitle( page_title );
 +		else
 +			setTitle( mCurrentURL );
 +	}
 +	else if(event == MEDIA_EVENT_LINK_HOVERED )
 +	{
 +		const std::string link = self->getHoverLink();
 +		mStatusBarText->setText( link );
 +	}
 +}
 +
 +void LLFloaterWebContent::set_current_url(const std::string& url)
 +{
 +	mCurrentURL = url;
 +
 +	// serialize url history into the system URL History manager
 +	LLURLHistory::removeURL("browser", mCurrentURL);
 +	LLURLHistory::addURL("browser", mCurrentURL);
 +
 +	mAddressCombo->remove( mCurrentURL );
 +	mAddressCombo->add( mCurrentURL );
 +	mAddressCombo->selectByValue( mCurrentURL );
 +}
 +
 +void LLFloaterWebContent::onClickForward()
 +{
 +	mWebBrowser->navigateForward();
 +}
 +
 +void LLFloaterWebContent::onClickBack()
 +{
 +	mWebBrowser->navigateBack();
 +}
 +
 +void LLFloaterWebContent::onClickReload()
 +{
 +
 +	if( mWebBrowser->getMediaPlugin() )
 +	{
 +		bool ignore_cache = true;
 +		mWebBrowser->getMediaPlugin()->browse_reload( ignore_cache );
 +	}
 +	else
 +	{
 +		mWebBrowser->navigateTo(mCurrentURL);
 +	}
 +}
 +
 +void LLFloaterWebContent::onClickStop()
 +{
 +	if( mWebBrowser->getMediaPlugin() )
 +		mWebBrowser->getMediaPlugin()->browse_stop();
 +
 +	// still should happen when we catch the navigate complete event
 +	// but sometimes (don't know why) that event isn't sent from Qt
 +	// and we getto a point where the stop button stays active.
 +	getChildView("reload")->setVisible( true );
 +	getChildView("stop")->setVisible( false );
 +}
 +
 +void LLFloaterWebContent::onEnterAddress()
 +{
 +	// make sure there is at least something there.
 +	// (perhaps this test should be for minimum length of a URL)
 +	std::string url = mAddressCombo->getValue().asString();
 +	if ( url.length() > 0 )
 +	{
 +		mWebBrowser->navigateTo( url, "text/html");
 +	};
 +}
 +
 +void LLFloaterWebContent::onPopExternal()
 +{
 +	// make sure there is at least something there.
 +	// (perhaps this test should be for minimum length of a URL)
 +	std::string url = mAddressCombo->getValue().asString();
 +	if ( url.length() > 0 )
 +	{
 +		LLWeb::loadURLExternal( url );
 +	};
 +}
 diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h new file mode 100644 index 0000000000..001d822ada --- /dev/null +++ b/indra/newview/llfloaterwebcontent.h @@ -0,0 +1,82 @@ +/**
 + * @file llfloaterwebcontent.h
 + * @brief floater for displaying web content - e.g. profiles and search (eventually)
 + *
 + * $LicenseInfo:firstyear=2006&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$
 + */
 +
 +#ifndef LL_LLFLOATERWEBCONTENT_H
 +#define LL_LLFLOATERWEBCONTENT_H
 +
 +#include "llfloater.h"
 +#include "llmediactrl.h"
 +
 +class LLMediaCtrl;
 +class LLComboBox;
 +class LLTextBox;
 +class LLProgressBar;
 +class LLIconCtrl;
 +
 +class LLFloaterWebContent :
 +	public LLFloater,
 +	public LLViewerMediaObserver
 +{
 +public:
 +    LOG_CLASS(LLFloaterWebContent);
 +	LLFloaterWebContent(const LLSD& key);
 +
 +	void initializeURLHistory(); +
 +	static void create(const std::string &url, const std::string& target, const std::string& uuid = LLStringUtil::null);
 +
 +	static void closeRequest(const std::string &uuid);
 +	static void geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height);
 +	void geometryChanged(S32 x, S32 y, S32 width, S32 height);
 +
 +	/* virtual */ BOOL postBuild();
 +	/* virtual */ void onClose(bool app_quitting);
 +	/* virtual */ void draw();
 +
 +	// inherited from LLViewerMediaObserver
 +	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
 +
 +	void onClickBack();
 +	void onClickForward();
 +	void onClickReload();
 +	void onClickStop();
 +	void onEnterAddress();
 +	void onPopExternal();
 +
 +private:
 +	void open_media(const std::string& media_url, const std::string& target);
 +	void set_current_url(const std::string& url);
 +
 +	LLMediaCtrl* mWebBrowser;
 +	LLComboBox* mAddressCombo;
 +	LLIconCtrl *mSecureLockIcon;
 +	LLTextBox* mStatusBarText;
 +	LLProgressBar* mStatusBarProgress;
 +	std::string mCurrentURL;
 +	std::string mUUID;
 +};
 +
 +#endif  // LL_LLFLOATERWEBCONTENT_H
 diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 0f66713ab0..8d8f9dbebb 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -25,7 +25,7 @@   */  #include "llviewerprecompiledheaders.h" - +#include "lltooltip.h"  #include "llmediactrl.h" @@ -54,6 +54,10 @@  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llnotifications.h" +#include "lllineeditor.h" +#include "llfloatermediabrowser.h" +#include "llfloaterwebcontent.h" +#include "llwindowshade.h"  extern BOOL gRestoreGL; @@ -98,7 +102,9 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :  	mTextureHeight ( 1024 ),  	mClearCache(false),  	mHomePageMimeType(p.initial_mime_type), -	mTrusted(p.trusted_content) +	mTrusted(p.trusted_content), +	mWindowShade(NULL), +	mHoverTextChanged(false)  {  	{  		LLColor4 color = p.caret_color().get(); @@ -127,7 +133,7 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :  		setTextureSize(screen_width, screen_height);  	} -	mMediaTextureID.generate(); +	mMediaTextureID = getKey();  	// We don't need to create the media source up front anymore unless we have a non-empty home URL to navigate to.  	if(!mHomePageUrl.empty()) @@ -141,8 +147,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :  //	addChild( mBorder );  } -//////////////////////////////////////////////////////////////////////////////// -// note: this is now a singleton and destruction happens via initClass() now  LLMediaCtrl::~LLMediaCtrl()  { @@ -182,6 +186,13 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )  		mMediaSource->mouseMove(x, y, mask);  		gViewerWindow->setCursor(mMediaSource->getLastSetCursor());  	} +	 +	// TODO: Is this the right way to handle hover text changes driven by the plugin? +	if(mHoverTextChanged) +	{ +		mHoverTextChanged = false; +		handleToolTip(x, y, mask); +	}  	return TRUE;  } @@ -198,6 +209,35 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )  }  //////////////////////////////////////////////////////////////////////////////// +//	virtual  +BOOL LLMediaCtrl::handleToolTip(S32 x, S32 y, MASK mask) +{ +	std::string hover_text; +	 +	if (mMediaSource && mMediaSource->hasMedia()) +		hover_text = mMediaSource->getMediaPlugin()->getHoverText(); +	 +	if(hover_text.empty()) +	{ +		return FALSE; +	} +	else +	{ +		S32 screen_x, screen_y; + +		localPointToScreen(x, y, &screen_x, &screen_y); +		LLRect sticky_rect_screen; +		sticky_rect_screen.setCenterAndSize(screen_x, screen_y, 20, 20); + +		LLToolTipMgr::instance().show(LLToolTip::Params() +			.message(hover_text) +			.sticky_rect(sticky_rect_screen));		 +	} + +	return TRUE; +} + +////////////////////////////////////////////////////////////////////////////////  //  BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )  { @@ -338,85 +378,6 @@ 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;  } @@ -425,13 +386,15 @@ BOOL LLMediaCtrl::postBuild ()  //  BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )  { -	if (LLPanel::handleKeyHere(key, mask)) return TRUE;  	BOOL result = FALSE;  	if (mMediaSource)  	{  		result = mMediaSource->handleKeyHere(key, mask);  	} +	 +	if ( ! result ) +		result = LLPanel::handleKeyHere(key, mask);  	return result;  } @@ -451,7 +414,6 @@ void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility )  //  BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)  { -	if (LLPanel::handleUnicodeCharHere(uni_char)) return TRUE;  	BOOL result = FALSE;  	if (mMediaSource) @@ -459,6 +421,9 @@ BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)  		result = mMediaSource->handleUnicodeCharHere(uni_char);  	} +	if ( ! result ) +		result = LLPanel::handleUnicodeCharHere(uni_char); +  	return result;  } @@ -914,11 +879,6 @@ void LLMediaCtrl::draw()  	if ( mBorder && mBorder->getVisible() )  		mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) ); -	if (mCurNotification && !mCurNotification->isActive()) -	{ -		hideNotification(); -	} -	  	LLPanel::draw();  	// Restore the previous values @@ -1026,7 +986,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)  			LLNotification::Params notify_params;  			notify_params.name = "PopupAttempt"; -			notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", getKey()); +			notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", mMediaTextureID);  			notify_params.functor.function = boost::bind(&LLMediaCtrl::onPopup, this, _1, _2);  			if (mTrusted) @@ -1081,6 +1041,31 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)  			LL_DEBUGS("Media") << "Media event:  MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL;  		}  		break; + +		case MEDIA_EVENT_AUTH_REQUEST: +		{ +			LLNotification::Params auth_request_params; +			auth_request_params.name = "AuthRequest"; + +			// pass in host name and realm for site (may be zero length but will always exist) +			LLSD args; +			LLURL raw_url( self->getAuthURL().c_str() ); +			args["HOST_NAME"] = raw_url.getAuthority(); +			args["REALM"] = self->getAuthRealm(); +			auth_request_params.substitutions = args; + +			auth_request_params.payload = LLSD().with("media_id", mMediaTextureID); +			auth_request_params.functor.function = boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2, mMediaSource->getMediaPlugin()); +			LLNotifications::instance().add(auth_request_params); +		}; +		break; + +		case MEDIA_EVENT_LINK_HOVERED: +		{ +			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL; +			mHoverTextChanged = true; +		}; +		break;  	};  	// chain all events to any potential observers of this object. @@ -1098,109 +1083,85 @@ void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response)  {  	if (response["open"])  	{ -		LLWeb::loadURL(notification["payload"]["url"], notification["payload"]["target"], notification["payload"]["uuid"]); +		// name of default floater to open +		std::string floater_name = "media_browser"; + +		// look for parent floater name +		if ( gFloaterView ) +		{ +			if ( gFloaterView->getParentFloater(this) ) +			{ +				floater_name = gFloaterView->getParentFloater(this)->getInstanceName(); +			} +			else +			{ +				lldebugs << "No gFloaterView->getParentFloater(this) for onPopuup()" << llendl; +			}; +		} +		else +		{ +			lldebugs << "No gFloaterView for onPopuup()" << llendl; +		}; + +		// (for now) open web content floater if that's our parent, otherwise, open the current media floater +		// (this will change soon) +		if ( floater_name == "web_content" ) +		{ +			LLWeb::loadWebURL(notification["payload"]["url"], notification["payload"]["target"], notification["payload"]["uuid"]); +		} +		else +		{ +			LLWeb::loadURL(notification["payload"]["url"], notification["payload"]["target"], notification["payload"]["uuid"]); +		}  	}  	else  	{  		// Make sure the opening instance knows its window open request was denied, so it can clean things up.  		LLViewerMedia::proxyWindowClosed(notification["payload"]["uuid"]);  	} -  } -void LLMediaCtrl::onCloseNotification() -{ -	LLNotifications::instance().cancel(mCurNotification); -} - -void LLMediaCtrl::onClickIgnore(LLUICtrl* ctrl) +void LLMediaCtrl::showNotification(LLNotificationPtr notify)  { -	bool check = ctrl->getValue().asBoolean(); -	if (mCurNotification && mCurNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN) +	delete mWindowShade; + +	LLWindowShade::Params params; +	params.name = "notification_shade"; +	params.rect = getLocalRect(); +	params.follows.flags = FOLLOWS_ALL; +	params.notification = notify; +	params.modal = true; +	//HACK: don't hardcode this +	if (notify->getIcon() == "Popup_Caution")  	{ -		// question was "show again" so invert value to get "ignore" -		check = !check; +		params.bg_image.name = "Yellow_Gradient"; +		params.text_color = LLColor4::black;  	} -	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) +	else +	//HACK: another one since XUI doesn't support what we need right now +	if (notify->getName() == "AuthRequest")  	{ -		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; +		params.bg_image.name = "Yellow_Gradient"; +		params.text_color = LLColor4::black; +		params.can_close = false;  	} - -	for (S32 i = 0; i < formp->getNumElements(); i++) +	else  	{ -		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; -		} +		//HACK: make this a property of the notification itself, "cancellable" +		params.can_close = false; +		params.text_color.control = "LabelTextColor";  	} +	mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params); -	form_elements.reshape(cur_x, form_elements.getRect().getHeight()); - -	//LLWeb::loadURL(payload["url"], payload["target"]); +	addChild(mWindowShade); +	mWindowShade->show();  }  void LLMediaCtrl::hideNotification()  { -	LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area"); -	panel.setVisible(FALSE); - -	mCurNotification.reset(); +	if (mWindowShade) +	{ +		mWindowShade->hide(); +	}  } diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 96bb0c1df5..f95592551c 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -62,7 +62,6 @@ public:  		Optional<LLUIColor>		caret_color;  		Optional<std::string>	initial_mime_type; -		Optional<std::string>	media_id;  		Params();  	}; @@ -90,6 +89,7 @@ public:  		virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);  		virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );  		virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); +		virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);  		// navigation  		void navigateTo( std::string url_in, std::string mime_type = ""); @@ -168,9 +168,6 @@ 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; @@ -194,7 +191,8 @@ public:  		S32 mTextureWidth;  		S32 mTextureHeight;  		bool mClearCache; -		boost::shared_ptr<class LLNotification> mCurNotification; +		class LLWindowShade* mWindowShade; +		bool mHoverTextChanged;  };  #endif // LL_LLMediaCtrl_H diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 2e4be78be1..457e2d2980 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -212,9 +212,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,  	//sendChildToBack(getChildView("channel_text"));  	sendChildToBack(getChildView("forgot_password_text")); -	LLLineEditor* edit = getChild<LLLineEditor>("password_edit"); -	if (edit) edit->setDrawAsterixes(TRUE); -  	if(LLStartUp::getStartSLURL().getType() != LLSLURL::LOCATION)  	{  		LLSLURL slurl(gSavedSettings.getString("LoginLocation")); diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 614700fb0a..8ae3553857 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -59,6 +59,7 @@  #include "llvovolume.h"  #include "llweb.h"  #include "llwindow.h" +#include "llwindowshade.h"  #include "llfloatertools.h"  // to enable hide if build tools are up  // Functions pulled from pipeline.cpp @@ -90,7 +91,8 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() :  	mTargetObjectNormal(LLVector3::zero),  	mZoomObjectID(LLUUID::null),  	mZoomObjectFace(0), -	mVolumeSliderVisible(0) +	mVolumeSliderVisible(0), +	mWindowShade(NULL)  {  	mCommitCallbackRegistrar.add("MediaCtrl.Close",		boost::bind(&LLPanelPrimMediaControls::onClickClose, this));  	mCommitCallbackRegistrar.add("MediaCtrl.Back",		boost::bind(&LLPanelPrimMediaControls::onClickBack, this)); @@ -205,6 +207,9 @@ BOOL LLPanelPrimMediaControls::postBuild()  	mMediaAddress->setFocusReceivedCallback(boost::bind(&LLPanelPrimMediaControls::onInputURL, _1, this )); +	LLWindowShade::Params window_shade_params; +	window_shade_params.name = "window_shade"; +  	mCurrentZoom = ZOOM_NONE;  	// clicks on buttons do not remove keyboard focus from media  	setIsChrome(TRUE); @@ -698,6 +703,24 @@ void LLPanelPrimMediaControls::updateShape()  /*virtual*/  void LLPanelPrimMediaControls::draw()  { +	LLViewerMediaImpl* impl = getTargetMediaImpl(); +	if (impl) +	{ +		LLNotificationPtr notification = impl->getCurrentNotification(); +		if (notification != mActiveNotification) +		{ +			mActiveNotification = notification; +			if (notification) +			{ +				showNotification(notification); +			} +			else +			{ +				hideNotification(); +			} +		} +	} +  	F32 alpha = getDrawContext().mAlpha;  	if(mFadeTimer.getStarted())  	{ @@ -1295,3 +1318,38 @@ bool LLPanelPrimMediaControls::shouldVolumeSliderBeVisible()  {  	return mVolumeSliderVisible > 0;  } + +void LLPanelPrimMediaControls::showNotification(LLNotificationPtr notify) +{ +	delete mWindowShade; +	LLWindowShade::Params params; +	params.rect = mMediaRegion->getLocalRect(); +	params.follows.flags = FOLLOWS_ALL; +	params.notification = notify; + +	//HACK: don't hardcode this +	if (notify->getIcon() == "Popup_Caution") +	{ +		params.bg_image.name = "Yellow_Gradient"; +		params.text_color = LLColor4::black; +	} +	else +	{ +		//HACK: make this a property of the notification itself, "cancellable" +		params.can_close = false; +		params.text_color.control = "LabelTextColor"; +	} + +	mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params); + +	mMediaRegion->addChild(mWindowShade); +	mWindowShade->show(); +} + +void LLPanelPrimMediaControls::hideNotification() +{ +	if (mWindowShade) +	{ +		mWindowShade->hide(); +	} +} diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index 3ec24f0e24..0b9664359c 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -29,6 +29,7 @@  #include "llpanel.h"  #include "llviewermedia.h" +#include "llnotificationptr.h"  class LLButton;  class LLCoordWindow; @@ -37,6 +38,7 @@ class LLLayoutStack;  class LLProgressBar;  class LLSliderCtrl;  class LLViewerMediaImpl; +class LLWindowShade;  class LLPanelPrimMediaControls : public LLPanel  { @@ -54,6 +56,9 @@ public:  	void updateShape();  	bool isMouseOver(); +	void showNotification(LLNotificationPtr notify); +	void hideNotification(); +  	enum EZoomLevel  	{  		ZOOM_NONE = 0, @@ -162,6 +167,7 @@ private:  	LLUICtrl *mRightBookend;  	LLUIImage* mBackgroundImage;  	LLUIImage* mVolumeSliderBackgroundImage; +	LLWindowShade* mWindowShade;  	F32 mSkipStep;  	S32 mMinWidth;  	S32 mMinHeight; @@ -204,6 +210,8 @@ private:  	S32 mZoomObjectFace;  	S32 mVolumeSliderVisible; + +	LLNotificationPtr mActiveNotification;  };  #endif // LL_PANELPRIMMEDIACONTROLS_H diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index f573f25efe..dca1e33e60 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -60,6 +60,7 @@  #include "llfloaterhardwaresettings.h"  #include "llfloaterhelpbrowser.h"  #include "llfloatermediabrowser.h" +#include "llfloaterwebcontent.h"  #include "llfloatermediasettings.h"  #include "llfloaterhud.h"  #include "llfloaterimagepreview.h" @@ -252,6 +253,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);  	LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>); +	LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWebContent>);	  	LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>);	  	LLFloaterWindowSizeUtil::registerFloater();  	LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>);	 diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index fae4eb3c05..dacd663f83 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -52,6 +52,7 @@  #include "llviewerregion.h"  #include "llwebsharing.h"	// For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this!  #include "llfilepicker.h" +#include "llnotifications.h"  #include "llevent.h"		// LLSimpleListener  #include "llnotificationsutil.h" @@ -62,6 +63,7 @@  #include "llwindow.h"  #include "llfloatermediabrowser.h"	// for handling window close requests and geometry change requests in media browser windows. +#include "llfloaterwebcontent.h"	// for handling window close requests and geometry change requests in media browser windows.  #include <boost/bind.hpp>	// for SkinFolder listener  #include <boost/signals2.hpp> @@ -293,6 +295,7 @@ public:  LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;  LLURL LLViewerMedia::sOpenIDURL;  std::string LLViewerMedia::sOpenIDCookie; +LLPluginClassMedia* LLViewerMedia::sSpareBrowserMediaSource = NULL;  static LLViewerMedia::impl_list sViewerMediaImplList;  static LLViewerMedia::impl_id_map sViewerMediaTextureIDMap;  static LLTimer sMediaCreateTimer; @@ -742,6 +745,9 @@ void LLViewerMedia::updateMedia(void *dummy_arg)  	// Enable/disable the plugin read thread  	LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread")); +	// HACK: we always try to keep a spare running webkit plugin around to improve launch times. +	createSpareBrowserMediaSource(); +	  	sAnyMediaShowing = false;  	sUpdatedCookies = getCookieStore()->getChangedCookies();  	if(!sUpdatedCookies.empty()) @@ -759,6 +765,12 @@ void LLViewerMedia::updateMedia(void *dummy_arg)  		pimpl->update();  		pimpl->calculateInterest();  	} +	 +	// Let the spare media source actually launch +	if(sSpareBrowserMediaSource) +	{ +		sSpareBrowserMediaSource->idle(); +	}  	// Sort the static instance list using our interest criteria  	sViewerMediaImplList.sort(priorityComparitor); @@ -1034,6 +1046,18 @@ bool LLViewerMedia::isParcelAudioPlaying()  	return (LLViewerMedia::hasParcelAudio() && gAudiop && LLAudioEngine::AUDIO_PLAYING == gAudiop->isInternetStreamPlaying());  } +void LLViewerMedia::onAuthSubmit(const LLSD& notification, const LLSD& response, LLPluginClassMedia* media) +{ +	if (response["ok"]) +	{ +		media->sendAuthResponse(true, response["username"], response["password"]); +	} +	else +	{ +		media->sendAuthResponse(false, "", ""); +	} +} +  /////////////////////////////////////////////////////////////////////////////////////////  // static  void LLViewerMedia::clearAllCookies() @@ -1400,6 +1424,29 @@ void LLViewerMedia::proxyWindowClosed(const std::string &uuid)  	}  } +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::createSpareBrowserMediaSource() +{ +	if(!sSpareBrowserMediaSource) +	{ +		// If we don't have a spare browser media source, create one. +		// The null owner will keep the browser plugin from fully initializing  +		// (specifically, it keeps LLPluginClassMedia from negotiating a size change,  +		// which keeps MediaPluginWebkit::initBrowserWindow from doing anything until we have some necessary data, like the background color) +		sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType("text/html", NULL, 0, 0); +	} +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +LLPluginClassMedia* LLViewerMedia::getSpareBrowserMediaSource()  +{ +	LLPluginClassMedia* result = sSpareBrowserMediaSource; +	sSpareBrowserMediaSource = NULL; +	return result;  +}; +  bool LLViewerMedia::hasInWorldMedia()  {  	if (sInWorldMediaDisabled) return false; @@ -1636,6 +1683,21 @@ void LLViewerMediaImpl::setMediaType(const std::string& media_type)  LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, const std::string target)  {  	std::string plugin_basename = LLMIMETypes::implType(media_type); +	LLPluginClassMedia* media_source = NULL; +	 +	// HACK: we always try to keep a spare running webkit plugin around to improve launch times. +	if(plugin_basename == "media_plugin_webkit") +	{ +		media_source = LLViewerMedia::getSpareBrowserMediaSource(); +		if(media_source) +		{ +			media_source->setOwner(owner); +			media_source->setTarget(target); +			media_source->setSize(default_width, default_height); +						 +			return media_source; +		} +	}  	if(plugin_basename.empty())  	{ @@ -1673,7 +1735,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_  		}  		else  		{ -			LLPluginClassMedia* media_source = new LLPluginClassMedia(owner); +			media_source = new LLPluginClassMedia(owner);  			media_source->setSize(default_width, default_height);  			media_source->setUserDataPath(user_data_path);  			media_source->setLanguageCode(LLUI::getLanguage()); @@ -1753,6 +1815,22 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)  		media_source->focus(mHasFocus);  		media_source->setBackgroundColor(mBackgroundColor); +		if(gSavedSettings.getBOOL("BrowserIgnoreSSLCertErrors")) +		{ +			media_source->ignore_ssl_cert_errors(true); +		} + +		// start by assuming the default CA file will be used +		std::string ca_path = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "CA.pem" ); +	 +		// default turned off so pick up the user specified path +		if( ! gSavedSettings.getBOOL("BrowserUseDefaultCAFile")) +		{ +			ca_path = gSavedSettings.getString("BrowserCAFilePath"); +		} +		// set the path to the CA.pem file +		media_source->setCertificateFilePath( ca_path ); +  		media_source->proxy_setup(gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort"));  		if(mClearCache) @@ -1849,6 +1927,18 @@ void LLViewerMediaImpl::setSize(int width, int height)  }  ////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::showNotification(LLNotificationPtr notify) +{ +	mNotification = notify; +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::hideNotification() +{ +	mNotification.reset(); +} + +//////////////////////////////////////////////////////////////////////////////////////////  void LLViewerMediaImpl::play()  {  	// If the media source isn't there, try to initialize it and load an URL. @@ -2850,7 +2940,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla  			LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL;   			std::string url = plugin->getClickURL();  			LLURLDispatcher::dispatch(url, NULL, mTrustedBrowser); -  		}  		break;  		case MEDIA_EVENT_CLICK_LINK_HREF: @@ -2913,6 +3002,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla  		case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_BEGIN:  		{  			LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_BEGIN, uri is: " << plugin->getNavigateURI() << LL_ENDL; +			hideNotification();  			if(getNavState() == MEDIANAVSTATE_SERVER_SENT)  			{ @@ -3003,7 +3093,26 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla  			plugin->sendPickFileResponse(response);  		}  		break; -		 + + +		case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST: +		{ +			LLNotification::Params auth_request_params; +			auth_request_params.name = "AuthRequest"; + +			// pass in host name and realm for site (may be zero length but will always exist) +			LLSD args; +			LLURL raw_url( plugin->getAuthURL().c_str() ); +			args["HOST_NAME"] = raw_url.getAuthority(); +			args["REALM"] = plugin->getAuthRealm(); +			auth_request_params.substitutions = args; + +			auth_request_params.payload = LLSD().with("media_id", mTextureId); +			auth_request_params.functor.function = boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2, plugin); +			LLNotifications::instance().add(auth_request_params); +		}; +		break; +  		case LLViewerMediaObserver::MEDIA_EVENT_CLOSE_REQUEST:  		{  			std::string uuid = plugin->getClickUUID(); @@ -3019,6 +3128,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla  				// This close request is directed at another instance  				pass_through = false;  				LLFloaterMediaBrowser::closeRequest(uuid); +				LLFloaterWebContent::closeRequest(uuid);  			}  		}  		break; @@ -3038,6 +3148,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla  				// This request is directed at another instance  				pass_through = false;  				LLFloaterMediaBrowser::geometryChanged(uuid, plugin->getGeometryX(), plugin->getGeometryY(), plugin->getGeometryWidth(), plugin->getGeometryHeight()); +				LLFloaterWebContent::geometryChanged(uuid, plugin->getGeometryX(), plugin->getGeometryY(), plugin->getGeometryWidth(), plugin->getGeometryHeight());  			}  		}  		break; @@ -3521,6 +3632,11 @@ bool LLViewerMediaImpl::isInAgentParcel() const  	return result;  } +LLNotificationPtr LLViewerMediaImpl::getCurrentNotification() const +{ +	return mNotification; +} +  //////////////////////////////////////////////////////////////////////////////////////////  //  // static diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 4025a4484f..83fe790839 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -37,6 +37,7 @@  #include "llpluginclassmedia.h"  #include "v4color.h" +#include "llnotificationptr.h"  #include "llurl.h" @@ -130,6 +131,8 @@ public:  	static bool isParcelMediaPlaying();  	static bool isParcelAudioPlaying(); +	static void onAuthSubmit(const LLSD& notification, const LLSD& response, LLPluginClassMedia* media); +  	// Clear all cookies for all plugins  	static void clearAllCookies(); @@ -155,6 +158,9 @@ public:  	static void proxyWindowOpened(const std::string &target, const std::string &uuid);  	static void proxyWindowClosed(const std::string &uuid); +	static void createSpareBrowserMediaSource(); +	static LLPluginClassMedia* getSpareBrowserMediaSource(); +	  private:  	static void setOpenIDCookie();  	static void onTeleportFinished(); @@ -162,6 +168,7 @@ private:  	static LLPluginCookieStore *sCookieStore;  	static LLURL sOpenIDURL;  	static std::string sOpenIDCookie; +	static LLPluginClassMedia* sSpareBrowserMediaSource;  };  // Implementation functions not exported into header file @@ -195,6 +202,9 @@ public:  	LLPluginClassMedia* getMediaPlugin() { return mMediaSource; }  	void setSize(int width, int height); +	void showNotification(LLNotificationPtr notify); +	void hideNotification(); +  	void play();  	void stop();  	void pause(); @@ -387,6 +397,9 @@ public:  	// Is this media in the agent's parcel?  	bool isInAgentParcel() const; +	// get currently active notification associated with this media instance +	LLNotificationPtr getCurrentNotification() const; +  private:  	bool isAutoPlayable() const;  	bool shouldShowBasedOnClass() const; @@ -444,7 +457,8 @@ private:  	bool mNavigateSuspendedDeferred;  	bool mTrustedBrowser;  	std::string mTarget; -	 +	LLNotificationPtr mNotification; +  private:  	BOOL mIsUpdated ;  	std::list< LLVOVolume* > mObjectList ; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index e18b4ec414..9e16bf2fbb 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7223,6 +7223,12 @@ void handle_web_browser_test(const LLSD& param)  	LLWeb::loadURLInternal(url);  } +void handle_web_content_test(const LLSD& param) +{ +	std::string url = param.asString(); +	LLWeb::loadWebURLInternal(url); +} +  void handle_buy_currency_test(void*)  {  	std::string url = @@ -7973,7 +7979,8 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedDumpRegionObjectCache(), "Advanced.DumpRegionObjectCache");  	// Advanced > UI -	commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); +	commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test,	_2));	// sigh! this one opens the MEDIA browser +	commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2));	// this one opens the Web Content floater  	view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");  	view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");  	view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory"); diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 99e869dafc..40f0b43313 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -586,6 +586,18 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent  			LL_DEBUGS("Media") << "Media event:  MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL;  		}  		break; + +		case MEDIA_EVENT_AUTH_REQUEST: +		{ +			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() << ", realm " << self->getAuthRealm() << LL_ENDL; +		} +		break; + +		case MEDIA_EVENT_LINK_HOVERED: +		{ +			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL; +		}; +		break;  	};  } diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index 6028a8fbea..b73017a51a 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -35,6 +35,7 @@  #include "llagent.h"  #include "llappviewer.h"  #include "llfloatermediabrowser.h" +#include "llfloaterwebcontent.h"  #include "llfloaterreg.h"  #include "lllogininstance.h"  #include "llparcel.h" @@ -95,6 +96,23 @@ void LLWeb::loadURL(const std::string& url, const std::string& target, const std  	}  } +// static +void LLWeb::loadWebURL(const std::string& url, const std::string& target, const std::string& uuid) +{ +	if(target == "_internal") +	{ +		// Force load in the internal browser, as if with a blank target. +		loadWebURLInternal(url, "", uuid); +	} +	else if (gSavedSettings.getBOOL("UseExternalBrowser") || (target == "_external")) +	{ +		loadURLExternal(url); +	} +	else +	{ +		loadWebURLInternal(url, target, uuid); +	} +}  // static  void LLWeb::loadURLInternal(const std::string &url, const std::string& target, const std::string& uuid) @@ -102,6 +120,13 @@ void LLWeb::loadURLInternal(const std::string &url, const std::string& target, c  	LLFloaterMediaBrowser::create(url, target, uuid);  } +// static +// Explicitly open a Web URL using the Web content floater +void LLWeb::loadWebURLInternal(const std::string &url, const std::string& target, const std::string& uuid) +{ +	LLFloaterWebContent::create(url, target, uuid); +} +  // static  void LLWeb::loadURLExternal(const std::string& url, const std::string& uuid) diff --git a/indra/newview/llweb.h b/indra/newview/llweb.h index 2915376583..dc5958e57f 100644 --- a/indra/newview/llweb.h +++ b/indra/newview/llweb.h @@ -57,6 +57,11 @@ public:  	static void loadURLExternal(const std::string& url, const std::string& uuid);  	static void loadURLExternal(const std::string& url, bool async, const std::string& uuid = LLStringUtil::null); +	// Explicitly open a Web URL using the Web content floater vs. the more general media browser +	static void loadWebURL(const std::string& url, const std::string& target, const std::string& uuid); +	static void loadWebURLInternal(const std::string &url, const std::string& target, const std::string& uuid); +	static void loadWebURLInternal(const std::string &url) { loadWebURLInternal(url, LLStringUtil::null, LLStringUtil::null); } +  	/// Returns escaped url (eg, " " to "%20") - used by all loadURL methods  	static std::string escapeURL(const std::string& url);  	/// Expands various strings like [LANG], [VERSION], etc. in a URL diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index a51a096482..89611d8899 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -392,7 +392,7 @@ with the same filename but different name    <texture name="RadioButton_On_Disabled" file_name="widgets/RadioButton_On_Disabled.png" preload="true" /> -  <texture name="Refresh_Off" file_name="icons/Refresh_Off.png" preload="false" /> +  <texture name="Refresh_Off" file_name="icons/Refresh_Off.png" preload="true" />    <texture name="Resize_Corner" file_name="windows/Resize_Corner.png" preload="true" /> @@ -468,7 +468,7 @@ with the same filename but different name    <texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="false" />    <texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="false" /> -  <texture name="Stop_Off" file_name="icons/Stop_Off.png" preload="false" /> +  <texture name="Stop_Off" file_name="icons/Stop_Off.png" preload="true" />    <texture name="StopReload_Off" file_name="icons/StopReload_Off.png" preload="false" />    <texture name="StopReload_Over" file_name="icons/StopReload_Over.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/en/floater_help_browser.xml b/indra/newview/skins/default/xui/en/floater_help_browser.xml index 837923bcf6..02e50ee584 100644 --- a/indra/newview/skins/default/xui/en/floater_help_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml @@ -36,7 +36,8 @@           user_resize="false"           width="620">              <web_browser -              trusted_content="true"  +             trusted_content="true"  +             initial_mime_type="text/html"                bottom="-25"               follows="left|right|top|bottom"               layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml new file mode 100644 index 0000000000..2ad46824c2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_web_content.xml @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 +<floater
 +  legacy_header_height="18"
 +  can_resize="true"
 +  height="440"
 +  layout="topleft"
 +  min_height="140"
 +  min_width="467"
 +  name="floater_web_content"
 +  help_topic="floater_web_content"
 +  save_rect="true"
 +  auto_tile="true"
 +  title=""
 +  initial_mime_type="text/html"
 +  width="820">
 +  <layout_stack
 +    bottom="440"
 +    follows="left|right|top|bottom"
 +    layout="topleft"
 +    left="5"
 +    name="stack1"
 +    orientation="vertical"
 +    top="20"
 +    width="810">
 +    <layout_panel
 +      auto_resize="false"
 +      default_tab_group="1"
 +      height="22"
 +      layout="topleft"
 +      left="0"
 +      min_height="20"
 +      name="nav_controls"
 +      top="400"
 +      user_resize="false"
 +      width="800">
 +      <button
 +        image_overlay="Arrow_Left_Off"
 +		    image_disabled="PushButton_Disabled"
 +		    image_disabled_selected="PushButton_Disabled"
 +		    image_selected="PushButton_Selected"
 +		    image_unselected="PushButton_Off"
 +		    hover_glow_amount="0.15"
 +        tool_tip="Navigate back"
 +        follows="left|top"
 +        height="22"
 +        layout="topleft"
 +        left="1"
 +        name="back"
 +        top="0"
 +        width="22">
 +        <button.commit_callback
 +          function="WebContent.Back" />
 +      </button>
 +      <button
 +        image_overlay="Arrow_Right_Off"
 +		    image_disabled="PushButton_Disabled"
 +		    image_disabled_selected="PushButton_Disabled"
 +		    image_selected="PushButton_Selected"
 +		    image_unselected="PushButton_Off"
 +        tool_tip="Navigate forward"
 +        follows="left|top"
 +        height="22"
 +        layout="topleft"
 +        left="27"
 +        name="forward"
 +        top_delta="0"
 +        width="22">
 +        <button.commit_callback
 +          function="WebContent.Forward" />
 +      </button>
 +      <button
 +        image_overlay="Stop_Off"
 +		    image_disabled="PushButton_Disabled"
 +		    image_disabled_selected="PushButton_Disabled"
 +		    image_selected="PushButton_Selected"
 +		    image_unselected="PushButton_Off"
 +        tool_tip="Stop navigation"
 +        enabled="true"
 +        follows="left|top"
 +        height="22"
 +        layout="topleft"
 +        left="51"
 +        name="stop"
 +        top_delta="0"
 +        width="22">
 +        <button.commit_callback
 +          function="WebContent.Stop" />
 +      </button>
 +      <button
 +        image_overlay="Refresh_Off"
 +		    image_disabled="PushButton_Disabled"
 +		    image_disabled_selected="PushButton_Disabled"
 +		    image_selected="PushButton_Selected"
 +		    image_unselected="PushButton_Off"
 +        tool_tip="Reload page"
 +        follows="left|top"
 +        height="22"
 +        layout="topleft"
 +        left="51"
 +        name="reload"
 +        top_delta="0"
 +        width="22">
 +        <button.commit_callback
 +          function="WebContent.Reload" />
 +      </button>
 +      <combo_box
 +        allow_text_entry="true"
 +        follows="left|top|right"
 +        tab_group="1"
 +        height="22"
 +        layout="topleft"
 +        left_pad="4"
 +        max_chars="1024"
 +        name="address"
 +        combo_editor.select_on_focus="true"
 +        tool_tip="Enter URL here"
 +        top_delta="0"
 +        width="702">
 +        <combo_box.commit_callback
 +          function="WebContent.EnterAddress" />
 +      </combo_box>
 +      <icon
 +        name="media_secure_lock_flag"
 +        height="16"
 +        follows="top|right"
 +        image_name="Lock2"
 +        layout="topleft"
 +        left_delta="656"
 +        top_delta="2"
 +        visible="false" 
 +        tool_tip="Secured Browsing"
 +        width="16" />
 +      <button
 +        image_overlay="ExternalBrowser_Off"
 +		    image_disabled="PushButton_Disabled"
 +		    image_disabled_selected="PushButton_Disabled"
 +		    image_selected="PushButton_Selected"
 +		    image_unselected="PushButton_Off"
 +        tool_tip="Open current URL in your desktop browser"
 +        follows="right|top"
 +        enabled="true" 
 +        height="22"
 +        layout="topleft"
 +        name="popexternal"
 +        right="800"
 +        top_delta="-2"
 +        width="22">
 +        <button.commit_callback
 +          function="WebContent.PopExternal" />
 +      </button>
 +    </layout_panel>
 +    <layout_panel
 +      height="40"
 +      layout="topleft"
 +      left_delta="0"
 +      name="external_controls"
 +      top_delta="0"
 +      user_resize="false"
 +      width="540">
 +      <web_browser
 +        bottom="-22"
 +        follows="all"
 +        layout="topleft"
 +        left="0"
 +        name="webbrowser"
 +        top="0"/>
 +      <text
 +        type="string"
 +        length="100"
 +        follows="bottom|left"
 +        height="20"
 +        layout="topleft"
 +        left_delta="0"
 +        name="statusbartext"
 +        parse_urls="false"
 +        text_color="0.4 0.4 0.4 1" 
 +        top_pad="5"
 +        width="452"/>
 +      <progress_bar
 +        color_bar="0.3 1.0 0.3 1"
 +        follows="bottom|right"
 +        height="16"
 +        top_delta="-1"
 +        left_pad="24"
 +        layout="topleft"
 +        name="statusbarprogress"
 +        width="64"/>
 +    </layout_panel>
 +  </layout_stack>
 +</floater>
 diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 4f982cc8e9..0d4a095e14 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -176,13 +176,19 @@               parameter="message_critical" />          </menu_item_call>          <menu_item_call -         label="Web Browser Test" +         label="Media Browser Test"           name="Web Browser Test">            <menu_item_call.on_click             function="Advanced.WebBrowserTest"             parameter="http://join.secondlife.com/"/>          </menu_item_call> -      <menu_item_separator/> +      <menu_item_call +       label="Web Content Floater Test" +       name="Web Content Floater Test"> +        <menu_item_call.on_click +         function="Advanced.WebContentTest" +         parameter="http://www.google.com"/> +      </menu_item_call>        <menu_item_check          label="Show Grid Picker"          name="Show Grid Picker" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 3b1ebc64ab..d997a262a8 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2646,13 +2646,21 @@                   parameter="BottomPanelNew" />              </menu_item_check>-->              <menu_item_call -             label="Web Browser Test" +             label="Media Browser Test"               name="Web Browser Test">                  <menu_item_call.on_click                   function="Advanced.WebBrowserTest"                   parameter="http://secondlife.com/app/search/slurls.html"/>              </menu_item_call> -            <menu_item_call +          <menu_item_call +           label="Web Content Browser" +           name="Web Content Browser" +           shortcut="control|alt|W"> +            <menu_item_call.on_click +             function="Advanced.WebContentTest" +             parameter="http://google.com"/> +          </menu_item_call> +          <menu_item_call               label="Dump SelectMgr"               name="Dump SelectMgr">                  <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index b1fd579c6f..11a4970488 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -5014,7 +5014,7 @@ If you want to view streaming media on parcels that support it you should go to     type="notify">  No Media Plugin was found to handle the "[MIME_TYPE]" mime type.  Media of this type will be unavailable.      <unique> -      <context key="[MIME_TYPE]"/> +      <context>MIME_TYPE</context>      </unique>    </notification> @@ -5943,7 +5943,7 @@ You may only select up to [MAX_SELECT] items from this list.  [NAME] is inviting you to a Voice Chat call.  Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.      <unique> -      <context key="NAME"/> +      <context>NAME</context>      </unique>      <form name="form">        <button @@ -5992,8 +5992,8 @@ Click Accept to join the call or Decline to decline the invitation. Click Block  [NAME] has joined a Voice Chat call with the group [GROUP].  Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.      <unique> -      <context key="NAME"/> -      <context key="GROUP"/> +      <context>NAME</context> +      <context>GROUP</context>      </unique>      <form name="form">        <button @@ -6018,7 +6018,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block  [NAME] has joined a voice chat call with a conference chat.  Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.      <unique> -      <context key="NAME"/> +      <context>NAME</context>      </unique>      <form name="form">        <button @@ -6043,7 +6043,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block  [NAME] is inviting you to a conference chat.  Click Accept to join the chat or Decline to decline the invitation. Click Block to block this caller.      <unique> -      <context key="NAME"/> +      <context>NAME</context>      </unique>      <form name="form">        <button @@ -6067,7 +6067,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block     type="notifytip">  The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later.      <unique> -      <context key="VOICE_CHANNEL_NAME"/> +      <context>VOICE_CHANNEL_NAME</context>      </unique>    </notification> @@ -6085,7 +6085,7 @@ We're sorry.  This area has reached maximum capacity for voice conversation     type="notifytip">  You have been disconnected from [VOICE_CHANNEL_NAME].  You will now be reconnected to Nearby Voice Chat.      <unique> -      <context key="VOICE_CHANNEL_NAME"/> +      <context>VOICE_CHANNEL_NAME</context>      </unique>    </notification> @@ -6095,7 +6095,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME].  You will now be reconnect     type="notifytip">  [VOICE_CHANNEL_NAME] has ended the call.  You will now be reconnected to Nearby Voice Chat.      <unique> -      <context key="VOICE_CHANNEL_NAME"/> +      <context>VOICE_CHANNEL_NAME</context>      </unique>    </notification> @@ -6105,7 +6105,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME].  You will now be reconnect     type="notifytip">  [VOICE_CHANNEL_NAME] has declined your call.  You will now be reconnected to Nearby Voice Chat.      <unique> -      <context key="VOICE_CHANNEL_NAME"/> +      <context>VOICE_CHANNEL_NAME</context>      </unique>    </notification> @@ -6115,7 +6115,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME].  You will now be reconnect     type="notifytip">  [VOICE_CHANNEL_NAME] is not available to take your call.  You will now be reconnected to Nearby Voice Chat.      <unique> -      <context key="VOICE_CHANNEL_NAME"/> +      <context>VOICE_CHANNEL_NAME</context>      </unique>    </notification> @@ -6125,7 +6125,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME].  You will now be reconnect     type="notifytip">  Failed to connect to [VOICE_CHANNEL_NAME], please try again later.  You will now be reconnected to Nearby Voice Chat.      <unique> -      <context key="VOICE_CHANNEL_NAME"/> +      <context>VOICE_CHANNEL_NAME</context>      </unique>    </notification> @@ -6211,7 +6211,7 @@ Cannot enter parcel, you are not on the access list.     type="notifytip">  You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME].      <unique> -      <context key="VOICE_CHANNEL_NAME"/> +      <context>VOICE_CHANNEL_NAME</context>      </unique>    </notification> @@ -6221,7 +6221,7 @@ You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME].     type="notifytip">  An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME].  Please try again later.      <unique> -      <context key="VOICE_CHANNEL_NAME"/> +      <context>VOICE_CHANNEL_NAME</context>      </unique>    </notification> @@ -6628,6 +6628,23 @@ Mute everyone?      </form>    </notification> +  <notification +  name="AuthRequest" +  type="browser"> +The site at '<nolink>[HOST_NAME]</nolink>' in realm '[REALM]' requires a user name and password. +    <form name="form"> +      <input name="username" type="text" text="User Name"/> +      <input name="password" type="password" text="Password    "/> +      <button default="true" +              index="0" +              name="ok" +              text="Submit"/> +      <button index="1" +              name="cancel" +              text="Cancel"/> +    </form> +  </notification> +    <global name="UnsupportedCPU">  - Your CPU speed does not meet the minimum requirements. diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index e3cd61c5aa..b5c584920f 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -92,6 +92,7 @@ follows="left|bottom"    height="22"    max_length_bytes="16"  name="password_edit" +is_password="true"   select_on_focus="true"    top_pad="0"    width="135" /> | 
