summaryrefslogtreecommitdiff
path: root/indra/newview/llmediactrl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llmediactrl.cpp')
-rw-r--r--indra/newview/llmediactrl.cpp326
1 files changed, 285 insertions, 41 deletions
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 7a4ed74c4c..e84c9152b1 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -2,31 +2,25 @@
* @file LLMediaCtrl.cpp
* @brief Web browser UI control
*
- * $LicenseInfo:firstyear=2006&license=viewergpl$
- *
- * Copyright (c) 2006-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 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.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 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.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * 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
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -44,7 +38,6 @@
#include "llviewermedia.h"
#include "llviewertexture.h"
#include "llviewerwindow.h"
-#include "llnotificationsutil.h"
#include "llweb.h"
#include "llrender.h"
#include "llpluginclassmedia.h"
@@ -54,6 +47,13 @@
// linden library includes
#include "llfocusmgr.h"
+#include "llsdutil.h"
+#include "lllayoutstack.h"
+#include "lliconctrl.h"
+#include "lltextbox.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llnotifications.h"
extern BOOL gRestoreGL;
@@ -67,19 +67,22 @@ LLMediaCtrl::Params::Params()
decouple_texture_size("decouple_texture_size", false),
texture_width("texture_width", 1024),
texture_height("texture_height", 1024),
- caret_color("caret_color")
+ caret_color("caret_color"),
+ initial_mime_type("initial_mime_type"),
+ media_id("media_id"),
+ trusted_content("trusted_content", false)
{
tab_stop(false);
}
LLMediaCtrl::LLMediaCtrl( const Params& p) :
LLPanel( p ),
+ LLInstanceTracker<LLMediaCtrl, LLUUID>(LLUUID::generateNewID()),
mTextureDepthBytes( 4 ),
mBorder(NULL),
mFrequentUpdates( true ),
mForceUpdate( false ),
mHomePageUrl( "" ),
- mTrusted(false),
mIgnoreUIScale( true ),
mAlwaysRefresh( false ),
mMediaSource( 0 ),
@@ -92,7 +95,9 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
mDecoupleTextureSize ( false ),
mTextureWidth ( 1024 ),
mTextureHeight ( 1024 ),
- mClearCache(false)
+ mClearCache(false),
+ mHomePageMimeType(p.initial_mime_type),
+ mTrusted(p.trusted_content)
{
{
LLColor4 color = p.caret_color().get();
@@ -101,7 +106,7 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
setIgnoreUIScale(p.ignore_ui_scale);
- setHomePageUrl(p.start_url);
+ setHomePageUrl(p.start_url, p.initial_mime_type);
setBorderVisible(p.border_visible);
@@ -165,19 +170,10 @@ void LLMediaCtrl::setTakeFocusOnClick( bool take_focus )
}
////////////////////////////////////////////////////////////////////////////////
-void LLMediaCtrl::setTrusted( bool valIn )
-{
- if(mMediaSource)
- {
- mMediaSource->setTrustedBrowser(valIn);
- }
- mTrusted = valIn;
-}
-
-////////////////////////////////////////////////////////////////////////////////
//
BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
{
+ if (LLPanel::handleHover(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
@@ -193,6 +189,7 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
//
BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
+ if (LLPanel::handleScrollWheel(x, y, clicks)) return TRUE;
if (mMediaSource && mMediaSource->hasMedia())
mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, gKeyboard->currentMask(TRUE));
@@ -203,6 +200,7 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
//
BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )
{
+ if (LLPanel::handleMouseUp(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
@@ -227,6 +225,7 @@ BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )
//
BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask )
{
+ if (LLPanel::handleMouseDown(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
@@ -246,6 +245,7 @@ BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask )
//
BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask )
{
+ if (LLPanel::handleRightMouseUp(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
@@ -270,6 +270,7 @@ BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask )
//
BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
+ if (LLPanel::handleRightMouseDown(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
@@ -289,6 +290,7 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )
//
BOOL LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask )
{
+ if (LLPanel::handleDoubleClick(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
@@ -343,6 +345,85 @@ void LLMediaCtrl::onFocusLost()
//
BOOL LLMediaCtrl::postBuild ()
{
+ LLLayoutStack::Params layout_p;
+ layout_p.name = "notification_stack";
+ layout_p.rect = LLRect(0,getLocalRect().mTop,getLocalRect().mRight, 30);
+ layout_p.follows.flags = FOLLOWS_ALL;
+ layout_p.mouse_opaque = false;
+ layout_p.orientation = "vertical";
+
+ LLLayoutStack* stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p);
+ addChild(stackp);
+
+ LLLayoutPanel::Params panel_p;
+ panel_p.rect = LLRect(0, 30, 800, 0);
+ panel_p.min_height = 30;
+ panel_p.name = "notification_area";
+ panel_p.visible = false;
+ panel_p.user_resize = false;
+ panel_p.background_visible = true;
+ panel_p.bg_alpha_image.name = "Yellow_Gradient";
+ panel_p.auto_resize = false;
+ LLLayoutPanel* notification_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+ stackp->addChild(notification_panel);
+
+ panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+ panel_p.auto_resize = true;
+ panel_p.mouse_opaque = false;
+ LLLayoutPanel* dummy_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+ stackp->addChild(dummy_panel);
+
+ layout_p = LLUICtrlFactory::getDefaultParams<LLLayoutStack>();
+ layout_p.rect = LLRect(0, 30, 800, 0);
+ layout_p.follows.flags = FOLLOWS_ALL;
+ layout_p.orientation = "horizontal";
+ stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p);
+ notification_panel->addChild(stackp);
+
+ panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+ panel_p.rect.height = 30;
+ LLLayoutPanel* panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+ stackp->addChild(panel);
+
+ LLIconCtrl::Params icon_p;
+ icon_p.name = "notification_icon";
+ icon_p.rect = LLRect(5, 23, 21, 8);
+ panel->addChild(LLUICtrlFactory::create<LLIconCtrl>(icon_p));
+
+ LLTextBox::Params text_p;
+ text_p.rect = LLRect(31, 20, 430, 0);
+ text_p.text_color = LLColor4::black;
+ text_p.font = LLFontGL::getFontSansSerif();
+ text_p.font.style = "BOLD";
+ text_p.name = "notification_text";
+ text_p.use_ellipses = true;
+ panel->addChild(LLUICtrlFactory::create<LLTextBox>(text_p));
+
+ panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+ panel_p.auto_resize = false;
+ panel_p.user_resize = false;
+ panel_p.name="form_elements";
+ panel_p.rect = LLRect(0, 30, 130, 0);
+ LLLayoutPanel* form_elements_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+ stackp->addChild(form_elements_panel);
+
+ panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+ panel_p.auto_resize = false;
+ panel_p.user_resize = false;
+ panel_p.rect = LLRect(0, 30, 25, 0);
+ LLLayoutPanel* close_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+ stackp->addChild(close_panel);
+
+ LLButton::Params button_p;
+ button_p.name = "close_notification";
+ button_p.rect = LLRect(5, 23, 21, 7);
+ button_p.image_color=LLUIColorTable::instance().getColor("DkGray_66");
+ button_p.image_unselected.name="Icon_Close_Foreground";
+ button_p.image_selected.name="Icon_Close_Press";
+ button_p.click_callback.function = boost::bind(&LLMediaCtrl::onCloseNotification, this);
+
+ close_panel->addChild(LLUICtrlFactory::create<LLButton>(button_p));
+
setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2));
return TRUE;
}
@@ -351,6 +432,7 @@ BOOL LLMediaCtrl::postBuild ()
//
BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )
{
+ if (LLPanel::handleKeyHere(key, mask)) return TRUE;
BOOL result = FALSE;
if (mMediaSource)
@@ -376,6 +458,7 @@ void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility )
//
BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)
{
+ if (LLPanel::handleUnicodeCharHere(uni_char)) return TRUE;
BOOL result = FALSE;
if (mMediaSource)
@@ -567,12 +650,21 @@ void LLMediaCtrl::navigateHome()
////////////////////////////////////////////////////////////////////////////////
//
-void LLMediaCtrl::setHomePageUrl( const std::string urlIn )
+void LLMediaCtrl::setHomePageUrl( const std::string& urlIn, const std::string& mime_type )
{
mHomePageUrl = urlIn;
if (mMediaSource)
{
- mMediaSource->setHomeURL(mHomePageUrl);
+ mMediaSource->setHomeURL(mHomePageUrl, mime_type);
+ }
+}
+
+void LLMediaCtrl::setTarget(const std::string& target)
+{
+ mTarget = target;
+ if (mMediaSource)
+ {
+ mMediaSource->setTarget(mTarget);
}
}
@@ -616,7 +708,8 @@ bool LLMediaCtrl::ensureMediaSourceExists()
if ( mMediaSource )
{
mMediaSource->setUsedInUI(true);
- mMediaSource->setHomeURL(mHomePageUrl);
+ mMediaSource->setHomeURL(mHomePageUrl, mHomePageMimeType);
+ mMediaSource->setTarget(mTarget);
mMediaSource->setVisible( getVisible() );
mMediaSource->addObserver( this );
mMediaSource->setBackgroundColor( getBackgroundColor() );
@@ -828,6 +921,10 @@ void LLMediaCtrl::draw()
if ( mBorder && mBorder->getVisible() )
mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) );
+ if (mCurNotification && !mCurNotification->isActive())
+ {
+ hideNotification();
+ }
LLPanel::draw();
@@ -894,6 +991,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
case MEDIA_EVENT_NAVIGATE_BEGIN:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL;
+ hideNotification();
};
break;
@@ -928,9 +1026,27 @@ 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();
+ std::string uuid = self->getClickUUID();
+
+ 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.functor.function = boost::bind(&LLMediaCtrl::onPopup, this, _1, _2);
+
+ if (mTrusted)
+ {
+ LLNotifications::instance().forceResponse(notify_params, 0);
+ }
+ else
+ {
+ LLNotifications::instance().add(notify_params);
+ }
+ break;
};
- break;
-
+
case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL;
@@ -954,6 +1070,24 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAME_CHANGED" << LL_ENDL;
};
break;
+
+ case MEDIA_EVENT_CLOSE_REQUEST:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL;
+ }
+ break;
+
+ case MEDIA_EVENT_PICK_FILE_REQUEST:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL;
+ }
+ break;
+
+ case MEDIA_EVENT_GEOMETRY_CHANGE:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL;
+ }
+ break;
};
// chain all events to any potential observers of this object.
@@ -967,3 +1101,113 @@ 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"], 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)
+{
+ bool check = ctrl->getValue().asBoolean();
+ if (mCurNotification && mCurNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
+ {
+ // question was "show again" so invert value to get "ignore"
+ check = !check;
+ }
+ mCurNotification->setIgnored(check);
+}
+
+void LLMediaCtrl::onClickNotificationButton(const std::string& name)
+{
+ if (!mCurNotification) return;
+
+ LLSD response = mCurNotification->getResponseTemplate();
+ response[name] = true;
+
+ mCurNotification->respond(response);
+}
+
+void LLMediaCtrl::showNotification(LLNotificationPtr notify)
+{
+ mCurNotification = notify;
+
+ // add popup here
+ LLSD payload = notify->getPayload();
+
+ LLNotificationFormPtr formp = notify->getForm();
+ LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area");
+ panel.setVisible(true);
+ panel.getChild<LLUICtrl>("notification_icon")->setValue(notify->getIcon());
+ panel.getChild<LLUICtrl>("notification_text")->setValue(notify->getMessage());
+ panel.getChild<LLUICtrl>("notification_text")->setToolTip(notify->getMessage());
+ LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType();
+ LLLayoutPanel& form_elements = panel.getChildRef<LLLayoutPanel>("form_elements");
+ form_elements.deleteAllChildren();
+
+ const S32 FORM_PADDING_HORIZONTAL = 10;
+ const S32 FORM_PADDING_VERTICAL = 3;
+ S32 cur_x = FORM_PADDING_HORIZONTAL;
+
+ if (ignore_type != LLNotificationForm::IGNORE_NO)
+ {
+ LLCheckBoxCtrl::Params checkbox_p;
+ checkbox_p.name = "ignore_check";
+ checkbox_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL);
+ checkbox_p.label = formp->getIgnoreMessage();
+ checkbox_p.label_text.text_color = LLColor4::black;
+ checkbox_p.commit_callback.function = boost::bind(&LLMediaCtrl::onClickIgnore, this, _1);
+ checkbox_p.initial_value = formp->getIgnored();
+
+ LLCheckBoxCtrl* check = LLUICtrlFactory::create<LLCheckBoxCtrl>(checkbox_p);
+ check->setRect(check->getBoundingRect());
+ form_elements.addChild(check);
+ cur_x = check->getRect().mRight + FORM_PADDING_HORIZONTAL;
+ }
+
+ for (S32 i = 0; i < formp->getNumElements(); i++)
+ {
+ LLSD form_element = formp->getElement(i);
+ if (form_element["type"].asString() == "button")
+ {
+ LLButton::Params button_p;
+ button_p.name = form_element["name"];
+ button_p.label = form_element["text"];
+ button_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL);
+ button_p.click_callback.function = boost::bind(&LLMediaCtrl::onClickNotificationButton, this, form_element["name"].asString());
+ button_p.auto_resize = true;
+
+ LLButton* button = LLUICtrlFactory::create<LLButton>(button_p);
+ button->autoResize();
+ form_elements.addChild(button);
+
+ cur_x = button->getRect().mRight + FORM_PADDING_HORIZONTAL;
+ }
+ }
+
+
+ form_elements.reshape(cur_x, form_elements.getRect().getHeight());
+
+ //LLWeb::loadURL(payload["url"], payload["target"]);
+}
+
+void LLMediaCtrl::hideNotification()
+{
+ LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area");
+ panel.setVisible(FALSE);
+
+ mCurNotification.reset();
+}