summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp55
-rw-r--r--indra/llplugin/llpluginclassmedia.h16
-rw-r--r--indra/llplugin/llpluginclassmediaowner.h6
-rw-r--r--indra/llui/lllayoutstack.cpp54
-rw-r--r--indra/llui/lllayoutstack.h20
-rw-r--r--indra/llui/lllineeditor.cpp3
-rw-r--r--indra/llui/lllineeditor.h3
-rw-r--r--indra/llui/llnotifications.cpp11
-rw-r--r--indra/llui/llnotifications.h1
-rw-r--r--indra/llui/llnotificationtemplate.h14
-rw-r--r--indra/media_plugins/webkit/media_plugin_webkit.cpp75
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/settings.xml46
-rw-r--r--indra/newview/llbrowsernotification.cpp2
-rw-r--r--indra/newview/llchathistory.cpp2
-rw-r--r--indra/newview/llfloaterhelpbrowser.cpp7
-rw-r--r--indra/newview/llfloatersearch.cpp2
-rw-r--r--indra/newview/llfloaterwebcontent.cpp304
-rw-r--r--indra/newview/llfloaterwebcontent.h77
-rw-r--r--indra/newview/llmediactrl.cpp515
-rw-r--r--indra/newview/llmediactrl.h9
-rw-r--r--indra/newview/llpanellogin.cpp3
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermedia.cpp74
-rw-r--r--indra/newview/llviewermedia.h4
-rw-r--r--indra/newview/llviewermenu.cpp9
-rw-r--r--indra/newview/llviewerparcelmedia.cpp12
-rw-r--r--indra/newview/llweb.cpp8
-rw-r--r--indra/newview/llweb.h4
-rw-r--r--indra/newview/skins/default/xui/en/floater_help_browser.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_web_content.xml153
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml9
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml45
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml1
-rw-r--r--indra/test_apps/llplugintest/llmediaplugintest.cpp15
36 files changed, 1321 insertions, 252 deletions
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 69ed0fb09c..de4456aa4e 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -160,7 +160,7 @@ void LLPluginClassMedia::idle(void)
mPlugin->idle();
}
- if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()))
+ if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()) || (mOwner == NULL))
{
// Can't process a size change at this time
}
@@ -522,7 +522,15 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
}
break;
}
-
+
+#if LL_DARWIN
+ if(modifiers & MASK_ALT)
+ {
+ // Option-key modified characters should be handled by the unicode input path instead of this one.
+ result = false;
+ }
+#endif
+
if(result)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "key_event");
@@ -682,6 +690,20 @@ void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
sendMessage(message);
}
+void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username, const std::string &password)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_response");
+ message.setValueBoolean("ok", ok);
+ message.setValue("username", username);
+ message.setValue("password", password);
+ if(mPlugin->isBlocked())
+ {
+ // If the plugin sent a blocking pick-file request, the response should unblock it.
+ message.setValueBoolean("blocking_response", true);
+ }
+ sendMessage(message);
+}
+
void LLPluginClassMedia::cut()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut");
@@ -947,6 +969,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);
}
+ else if(message_name == "auth_request")
+ {
+ mAuthURL = message.getValue("url");
+ mAuthRealm = message.getValue("realm");
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_AUTH_REQUEST);
+ }
else
{
LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
@@ -1019,6 +1047,15 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_GEOMETRY_CHANGE);
}
+ else if(message_name == "link_hovered")
+ {
+ // Link and text are not currently used -- the tooltip hover text is taken from the "title".
+ // message.getValue("link");
+ mHoverText = message.getValue("title");
+ // message.getValue("text");
+
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LINK_HOVERED);
+ }
else
{
LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
@@ -1192,6 +1229,20 @@ void LLPluginClassMedia::proxyWindowClosed(const std::string &uuid)
sendMessage(message);
}
+void LLPluginClassMedia::ignore_ssl_cert_errors(bool ignore)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "ignore_ssl_cert_errors");
+ message.setValueBoolean("ignore", ignore);
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::setCertificateFilePath(const std::string& path)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_certificate_file_path");
+ message.setValue("path", path);
+ sendMessage(message);
+}
+
void LLPluginClassMedia::crashPlugin()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash");
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 9cb67fe909..fa4dc2b43f 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -85,6 +85,8 @@ public:
void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; };
+ void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; };
+
// Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent.
// This will initially be false, and will also be false for some time after setSize while the resize is processed.
// Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values
@@ -159,6 +161,8 @@ public:
void sendPickFileResponse(const std::string &file);
+ void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
+
// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
std::string getCursorName() const { return mCursorName; };
@@ -198,6 +202,8 @@ public:
void setBrowserUserAgent(const std::string& user_agent);
void proxyWindowOpened(const std::string &target, const std::string &uuid);
void proxyWindowClosed(const std::string &uuid);
+ void ignore_ssl_cert_errors(bool ignore);
+ void setCertificateFilePath(const std::string& path);
// This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE
std::string getNavigateURI() const { return mNavigateURI; };
@@ -231,7 +237,14 @@ public:
S32 getGeometryY() const { return mGeometryY; };
S32 getGeometryWidth() const { return mGeometryWidth; };
S32 getGeometryHeight() const { return mGeometryHeight; };
+
+ // These are valid during MEDIA_EVENT_AUTH_REQUEST
+ std::string getAuthURL() const { return mAuthURL; };
+ std::string getAuthRealm() const { return mAuthRealm; };
+ // This is valid during MEDIA_EVENT_LINK_HOVERED
+ std::string getHoverText() const { return mHoverText; };
+
std::string getMediaName() const { return mMediaName; };
std::string getMediaDescription() const { return mMediaDescription; };
@@ -369,6 +382,9 @@ protected:
S32 mGeometryY;
S32 mGeometryWidth;
S32 mGeometryHeight;
+ std::string mAuthURL;
+ std::string mAuthRealm;
+ std::string mHoverText;
/////////////////////////////////////////
// media_time class
diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h
index c9efff216c..42e93cc6d7 100644
--- a/indra/llplugin/llpluginclassmediaowner.h
+++ b/indra/llplugin/llpluginclassmediaowner.h
@@ -59,7 +59,11 @@ public:
MEDIA_EVENT_GEOMETRY_CHANGE, // The plugin requested its window geometry be changed (per the javascript window interface)
MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch
- MEDIA_EVENT_PLUGIN_FAILED // The plugin died unexpectedly
+ MEDIA_EVENT_PLUGIN_FAILED, // The plugin died unexpectedly
+
+ MEDIA_EVENT_AUTH_REQUEST, // The plugin wants to display an auth dialog
+
+ MEDIA_EVENT_LINK_HOVERED // Got a "link hovered" event from the plugin
} EMediaEvent;
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 940c7e7e18..6c0a2a9a10 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -38,6 +38,12 @@
static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");
static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layout_panel("layout_panel");
+void LLLayoutStack::OrientationNames::declareValues()
+{
+ declare("horizontal", HORIZONTAL);
+ declare("vertical", VERTICAL);
+}
+
//
// LLLayoutPanel
//
@@ -47,47 +53,47 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
mMaxDim(p.max_dim),
mAutoResize(p.auto_resize),
mUserResize(p.user_resize),
- mCollapsed(FALSE),
- mCollapseAmt(0.f),
- mVisibleAmt(1.f), // default to fully visible
- mResizeBar(NULL)
- {
+ mCollapsed(FALSE),
+ mCollapseAmt(0.f),
+ mVisibleAmt(1.f), // default to fully visible
+ mResizeBar(NULL)
+{
// panels initialized as hidden should not start out partially visible
if (!getVisible())
- {
+ {
mVisibleAmt = 0.f;
- }
- }
+ }
+}
void LLLayoutPanel::initFromParams(const Params& p)
- {
+{
LLPanel::initFromParams(p);
setFollowsNone();
- }
+}
LLLayoutPanel::~LLLayoutPanel()
- {
- // probably not necessary, but...
- delete mResizeBar;
- mResizeBar = NULL;
- }
+{
+ // probably not necessary, but...
+ delete mResizeBar;
+ mResizeBar = NULL;
+}
F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation)
- {
+{
if (orientation == LLLayoutStack::HORIZONTAL)
- {
- F32 collapse_amt =
- clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth()));
- return mVisibleAmt * collapse_amt;
- }
- else
+ {
+ F32 collapse_amt =
+ clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth()));
+ return mVisibleAmt * collapse_amt;
+ }
+ else
{
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinDim / (F32)llmax(1, getRect().getHeight())));
return mVisibleAmt * collapse_amt;
- }
}
+}
//
// LLLayoutStack
@@ -107,7 +113,7 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)
mMinWidth(0),
mMinHeight(0),
mPanelSpacing(p.border_size),
- mOrientation((p.orientation() == "vertical") ? VERTICAL : HORIZONTAL),
+ mOrientation(p.orientation),
mAnimate(p.animate),
mAnimatedThisFrame(false),
mClip(p.clip)
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index e19ef403ef..9e8539c716 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -37,12 +37,24 @@ class LLLayoutPanel;
class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>
{
public:
+ typedef enum e_layout_orientation
+ {
+ HORIZONTAL,
+ VERTICAL
+ } ELayoutOrientation;
+
+ struct OrientationNames
+ : public LLInitParam::TypeValuesHelper<ELayoutOrientation, OrientationNames>
+ {
+ static void declareValues();
+ };
+
struct LayoutStackRegistry : public LLChildRegistry<LayoutStackRegistry>
{};
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
- Mandatory<std::string> orientation;
+ Mandatory<ELayoutOrientation, OrientationNames> orientation;
Optional<S32> border_size;
Optional<bool> animate,
clip;
@@ -52,12 +64,6 @@ public:
typedef LayoutStackRegistry child_registry_t;
- typedef enum e_layout_orientation
- {
- HORIZONTAL,
- VERTICAL
- } ELayoutOrientation;
-
virtual ~LLLayoutStack();
/*virtual*/ void draw();
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 3eb58e1aec..6ad1a0bac4 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -88,6 +88,7 @@ LLLineEditor::Params::Params()
revert_on_esc("revert_on_esc", true),
commit_on_focus_lost("commit_on_focus_lost", true),
ignore_tab("ignore_tab", true),
+ is_password("is_password", false),
cursor_color("cursor_color"),
text_color("text_color"),
text_readonly_color("text_readonly_color"),
@@ -129,7 +130,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mBorderThickness( 0 ),
mIgnoreArrowKeys( FALSE ),
mIgnoreTab( p.ignore_tab ),
- mDrawAsterixes( FALSE ),
+ mDrawAsterixes( p.is_password ),
mSelectAllonFocusReceived( p.select_on_focus ),
mPassDelete(FALSE),
mReadOnly(FALSE),
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index a1aa6b71c6..d9d36b73a3 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -85,7 +85,8 @@ public:
Optional<bool> select_on_focus,
revert_on_esc,
commit_on_focus_lost,
- ignore_tab;
+ ignore_tab,
+ is_password;
// colors
Optional<LLUIColor> cursor_color,
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index a3df6a3ced..15edf270bd 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -81,6 +81,7 @@ LLNotificationForm::FormButton::FormButton()
LLNotificationForm::FormInput::FormInput()
: type("type"),
+ text("text"),
max_length_chars("max_length_chars"),
width("width", 0),
value("value")
@@ -404,7 +405,7 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
it != end_it;
++it)
{
- mUniqueContext.push_back(it->key);
+ mUniqueContext.push_back(it->value);
}
mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form));
@@ -719,13 +720,19 @@ bool LLNotification::isEquivalentTo(LLNotificationPtr that) const
{
const LLSD& these_substitutions = this->getSubstitutions();
const LLSD& those_substitutions = that->getSubstitutions();
+ const LLSD& this_payload = this->getPayload();
+ const LLSD& that_payload = that->getPayload();
// highlander bit sez there can only be one of these
for (std::vector<std::string>::const_iterator it = mTemplatep->mUniqueContext.begin(), end_it = mTemplatep->mUniqueContext.end();
it != end_it;
++it)
{
- if (these_substitutions.get(*it).asString() != those_substitutions.get(*it).asString())
+ // if templates differ in either substitution strings or payload with the given field name
+ // then they are considered inequivalent
+ // use of get() avoids converting the LLSD value to a map as the [] operator would
+ if (these_substitutions.get(*it).asString() != those_substitutions.get(*it).asString()
+ || this_payload.get(*it).asString() != that_payload.get(*it).asString())
{
return false;
}
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 524cff70e8..a607f52b97 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -195,6 +195,7 @@ public:
Mandatory<std::string> type;
Optional<S32> width;
Optional<S32> max_length_chars;
+ Optional<std::string> text;
Optional<std::string> value;
FormInput();
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index 6bc0d2aaff..644d5c4d74 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -74,11 +74,13 @@ struct LLNotificationTemplate
struct UniquenessContext : public LLInitParam::Block<UniquenessContext>
{
- Mandatory<std::string> key;
+ Mandatory<std::string> value;
UniquenessContext()
- : key("key")
- {}
+ : value("value")
+ {
+ addSynonym(value, "key");
+ }
};
@@ -88,7 +90,7 @@ struct LLNotificationTemplate
// this idiom allows
// <notification unique="true">
// as well as
- // <notification> <unique> <context key=""/> </unique>...
+ // <notification> <unique> <context></context> </unique>...
Optional<bool> dummy_val;
public:
Multiple<UniquenessContext> contexts;
@@ -232,8 +234,8 @@ struct LLNotificationTemplate
// (used for things like progress indications, or repeating warnings
// like "the grid is going down in N minutes")
bool mUnique;
- // if we want to be unique only if a certain part of the payload is constant
- // specify the field names for the payload. The notification will only be
+ // if we want to be unique only if a certain part of the payload or substitutions args
+ // are constant specify the field names for the payload. The notification will only be
// combined if all of the fields named in the context are identical in the
// new and the old notification; otherwise, the notification will be
// duplicated. This is to support suppressing duplicate offers from the same
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
index bd1a44a930..19244d2d1f 100644
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
@@ -341,7 +341,7 @@ private:
url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundB * 255.0f);
url << "%22%3E%3C/body%3E%3C/html%3E";
- lldebugs << "data url is: " << url.str() << llendl;
+ //lldebugs << "data url is: " << url.str() << llendl;
LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, url.str() );
// LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" );
@@ -407,6 +407,8 @@ private:
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
message.setValue("uri", event.getEventUri());
+ message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK));
+ message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD));
sendMessage(message);
setStatus(STATUS_LOADING);
@@ -569,6 +571,57 @@ private:
return blockingPickFile();
}
+ std::string mAuthUsername;
+ std::string mAuthPassword;
+ bool mAuthOK;
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ bool onAuthRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password)
+ {
+ mAuthOK = false;
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request");
+ message.setValue("url", in_url);
+ message.setValue("realm", in_realm);
+ message.setValueBoolean("blocking_request", true);
+
+ // The "blocking_request" key in the message means this sendMessage call will block until a response is received.
+ sendMessage(message);
+
+ if(mAuthOK)
+ {
+ out_username = mAuthUsername;
+ out_password = mAuthPassword;
+ }
+
+ return mAuthOK;
+ }
+
+ void authResponse(LLPluginMessage &message)
+ {
+ mAuthOK = message.getValueBoolean("ok");
+ if(mAuthOK)
+ {
+ mAuthUsername = message.getValue("username");
+ mAuthPassword = message.getValue("password");
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ void onLinkHovered(const EventType& event)
+ {
+ if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "link_hovered");
+ message.setValue("link", event.getEventUri());
+ message.setValue("title", event.getStringValue());
+ message.setValue("text", event.getStringValue2());
+ sendMessage(message);
+ }
+ }
+
LLQtWebKit::EKeyboardModifier decodeModifiers(std::string &modifiers)
{
int result = 0;
@@ -1096,6 +1149,10 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
{
onPickFileResponse(message_in.getValue("file"));
}
+ if(message_name == "auth_response")
+ {
+ authResponse(message_in);
+ }
else
{
// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
@@ -1182,6 +1239,22 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
mUserAgent = message_in.getValue("user_agent");
LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
}
+ else if(message_name == "ignore_ssl_cert_errors")
+ {
+#if LLQTWEBKIT_API_VERSION >= 3
+ LLQtWebKit::getInstance()->setIgnoreSSLCertErrors( message_in.getValueBoolean("ignore") );
+#else
+ llwarns << "Ignoring ignore_ssl_cert_errors message (llqtwebkit version is too old)." << llendl;
+#endif
+ }
+ else if(message_name == "set_certificate_file_path")
+ {
+#if LLQTWEBKIT_API_VERSION >= 3
+ LLQtWebKit::getInstance()->setCAFile( message_in.getValue("path") );
+#else
+ llwarns << "Ignoring set_certificate_file_path message (llqtwebkit version is too old)." << llendl;
+#endif
+ }
else if(message_name == "init_history")
{
// Initialize browser history
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 679637caf6..aef5cfa51b 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 7dbb375a20..2158b95f4d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -674,6 +674,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>
@@ -6604,7 +6637,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..633ef4f1ce 100644
--- a/indra/newview/llbrowsernotification.cpp
+++ b/indra/newview/llbrowsernotification.cpp
@@ -29,8 +29,8 @@
#include "llnotificationhandler.h"
#include "llnotifications.h"
-#include "llfloaterreg.h"
#include "llmediactrl.h"
+#include "llviewermedia.h"
using namespace LLNotificationsUI;
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 271ee0c4a4..e933770601 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/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/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..8e5638f549
--- /dev/null
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -0,0 +1,304 @@
+/**
+ * @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 "llfloaterreg.h"
+#include "lllayoutstack.h"
+#include "llpluginclassmedia.h"
+#include "llprogressbar.h"
+#include "lltextbox.h"
+#include "llviewercontrol.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.EnterAddress", boost::bind( &LLFloaterWebContent::onEnterAddress, 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 button are always enabled
+ getChildView("reload")->setEnabled( true );
+
+ return TRUE;
+}
+
+//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)
+{
+ mWebBrowser->setHomePageUrl(web_url);
+ mWebBrowser->setTarget(target);
+ mWebBrowser->navigateTo(web_url);
+ set_current_url(web_url);
+}
+
+//virtual
+void LLFloaterWebContent::onClose(bool app_quitting)
+{
+ LLViewerMedia::proxyWindowClosed(mUUID);
+ destroy();
+}
+
+void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ if(event == MEDIA_EVENT_LOCATION_CHANGED)
+ {
+ const std::string url = self->getStatusText();
+
+ 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() );
+
+ // manually decide on the state of this button
+ getChildView("reload")->setVisible( false );
+ getChildView("stop")->setVisible( true );
+
+ // turn "on" progress bar now we're loaded
+ 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() );
+
+ // manually decide on the state of this button
+ getChildView("reload")->setVisible( true );
+ getChildView("stop")->setVisible( false );
+
+ // turn "off" progress bar now we're loaded
+ mStatusBarProgress->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();
+ setTitle( page_title );
+ }
+}
+
+void LLFloaterWebContent::set_current_url(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 );
+ }
+}
+
+void LLFloaterWebContent::onClickForward()
+{
+ mWebBrowser->navigateForward();
+}
+
+void LLFloaterWebContent::onClickBack()
+{
+ mWebBrowser->navigateBack();
+}
+
+void LLFloaterWebContent::onClickReload()
+{
+ mAddressCombo->remove(0);
+
+ if( mWebBrowser->getMediaPlugin() )
+ {
+ bool ignore_cache = true;
+ mWebBrowser->getMediaPlugin()->browse_reload( ignore_cache );
+ };
+}
+
+void LLFloaterWebContent::onClickStop()
+{
+ if( mWebBrowser->getMediaPlugin() )
+ mWebBrowser->getMediaPlugin()->stop();
+}
+
+void LLFloaterWebContent::onEnterAddress()
+{
+ mWebBrowser->navigateTo( mAddressCombo->getValue().asString() );
+}
diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h
new file mode 100644
index 0000000000..b41da57a6f
--- /dev/null
+++ b/indra/newview/llfloaterwebcontent.h
@@ -0,0 +1,77 @@
+/**
+ * @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 LLFloaterWebContent :
+ public LLFloater,
+ public LLViewerMediaObserver
+{
+public:
+ LOG_CLASS(LLFloaterWebContent);
+ LLFloaterWebContent(const LLSD& key);
+
+ 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);
+
+ // inherited from LLViewerMediaObserver
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+
+ void onClickBack();
+ void onClickForward();
+ void onClickReload();
+ void onClickStop();
+ void onEnterAddress();
+ void onClickGo();
+
+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;
+ 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 e84c9152b1..08d07f9540 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,11 +54,265 @@
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llnotifications.h"
+#include "lllineeditor.h"
extern BOOL gRestoreGL;
static LLDefaultChildRegistry::Register<LLMediaCtrl> r("web_browser");
+class LLWindowShade : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Mandatory<LLNotificationPtr> notification;
+ Optional<LLUIImage*> bg_image;
+
+ Params()
+ : bg_image("bg_image")
+ {
+ mouse_opaque = false;
+ }
+ };
+
+ void show();
+ /*virtual*/ void draw();
+ void hide();
+
+private:
+ friend class LLUICtrlFactory;
+
+ LLWindowShade(const Params& p);
+ void initFromParams(const Params& params);
+
+ void onCloseNotification();
+ void onClickNotificationButton(const std::string& name);
+ void onEnterNotificationText(LLUICtrl* ctrl, const std::string& name);
+ void onClickIgnore(LLUICtrl* ctrl);
+
+ LLNotificationPtr mNotification;
+ LLSD mNotificationResponse;
+};
+
+LLWindowShade::LLWindowShade(const LLWindowShade::Params& params)
+: LLView(params),
+ mNotification(params.notification)
+{
+}
+
+void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
+{
+ LLView::initFromParams(params);
+
+ 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 = LLLayoutStack::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 = params.bg_image;
+ 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 = LLLayoutStack::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(&LLWindowShade::onCloseNotification, this);
+
+ close_panel->addChild(LLUICtrlFactory::create<LLButton>(button_p));
+
+ LLSD payload = mNotification->getPayload();
+
+ LLNotificationFormPtr formp = mNotification->getForm();
+ LLLayoutPanel& notification_area = getChildRef<LLLayoutPanel>("notification_area");
+ notification_area.getChild<LLUICtrl>("notification_icon")->setValue(mNotification->getIcon());
+ notification_area.getChild<LLUICtrl>("notification_text")->setValue(mNotification->getMessage());
+ notification_area.getChild<LLUICtrl>("notification_text")->setToolTip(mNotification->getMessage());
+ LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType();
+ LLLayoutPanel& form_elements = notification_area.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(&LLWindowShade::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);
+ std::string type = form_element["type"].asString();
+ if (type == "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(&LLWindowShade::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;
+ }
+ else if (type == "text" || type == "password")
+ {
+ LLTextBox::Params label_p;
+ label_p.name = form_element["name"].asString() + "_label";
+ label_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x + 120, FORM_PADDING_VERTICAL);
+ label_p.initial_value = form_element["text"];
+ label_p.text_color = LLColor4::black;
+ LLTextBox* textbox = LLUICtrlFactory::create<LLTextBox>(label_p);
+ textbox->reshapeToFitText();
+ form_elements.addChild(textbox);
+ cur_x = textbox->getRect().mRight + FORM_PADDING_HORIZONTAL;
+
+ LLLineEditor::Params line_p;
+ line_p.name = form_element["name"];
+ line_p.commit_callback.function = boost::bind(&LLWindowShade::onEnterNotificationText, this, _1, form_element["name"].asString());
+ line_p.commit_on_focus_lost = true;
+ line_p.is_password = type == "password";
+ line_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x + 120, FORM_PADDING_VERTICAL);
+
+ LLLineEditor* line_editor = LLUICtrlFactory::create<LLLineEditor>(line_p);
+ form_elements.addChild(line_editor);
+ cur_x = line_editor->getRect().mRight + FORM_PADDING_HORIZONTAL;
+ }
+ }
+
+ form_elements.reshape(cur_x, form_elements.getRect().getHeight());
+}
+
+void LLWindowShade::show()
+{
+ LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area");
+ panel.setVisible(true);
+}
+
+void LLWindowShade::draw()
+{
+ LLView::draw();
+ if (mNotification && !mNotification->isActive())
+ {
+ hide();
+ }
+}
+
+void LLWindowShade::hide()
+{
+ LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area");
+ panel.setVisible(false);
+}
+
+void LLWindowShade::onCloseNotification()
+{
+ LLNotifications::instance().cancel(mNotification);
+}
+
+void LLWindowShade::onClickIgnore(LLUICtrl* ctrl)
+{
+ bool check = ctrl->getValue().asBoolean();
+ if (mNotification && mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
+ {
+ // question was "show again" so invert value to get "ignore"
+ check = !check;
+ }
+ mNotification->setIgnored(check);
+}
+
+void LLWindowShade::onClickNotificationButton(const std::string& name)
+{
+ if (!mNotification) return;
+
+ mNotificationResponse[name] = true;
+
+ mNotification->respond(mNotificationResponse);
+}
+
+void LLWindowShade::onEnterNotificationText(LLUICtrl* ctrl, const std::string& name)
+{
+ mNotificationResponse[name] = ctrl->getValue().asString();
+}
+
+
LLMediaCtrl::Params::Params()
: start_url("start_url"),
border_visible("border_visible", true),
@@ -69,7 +323,6 @@ LLMediaCtrl::Params::Params()
texture_height("texture_height", 1024),
caret_color("caret_color"),
initial_mime_type("initial_mime_type"),
- media_id("media_id"),
trusted_content("trusted_content", false)
{
tab_stop(false);
@@ -97,7 +350,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();
@@ -126,7 +381,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())
@@ -140,8 +395,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
// addChild( mBorder );
}
-////////////////////////////////////////////////////////////////////////////////
-// note: this is now a singleton and destruction happens via initClass() now
LLMediaCtrl::~LLMediaCtrl()
{
@@ -181,6 +434,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;
}
@@ -197,6 +457,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 )
{
@@ -345,85 +634,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;
}
@@ -432,13 +642,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;
}
@@ -458,7 +670,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)
@@ -466,6 +677,9 @@ BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)
result = mMediaSource->handleUnicodeCharHere(uni_char);
}
+ if ( ! result )
+ result = LLPanel::handleUnicodeCharHere(uni_char);
+
return result;
}
@@ -921,11 +1135,6 @@ void LLMediaCtrl::draw()
if ( mBorder && mBorder->getVisible() )
mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) );
- if (mCurNotification && !mCurNotification->isActive())
- {
- hideNotification();
- }
-
LLPanel::draw();
// Restore the previous values
@@ -1033,7 +1242,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)
@@ -1088,6 +1297,23 @@ 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";
+ auth_request_params.payload = LLSD().with("media_id", mMediaTextureID);
+ auth_request_params.functor.function = boost::bind(&LLMediaCtrl::onAuthSubmit, this, _1, _2);
+ 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.
@@ -1112,102 +1338,45 @@ void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response)
// 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()
+void LLMediaCtrl::onAuthSubmit(const LLSD& notification, const LLSD& response)
{
- LLNotifications::instance().cancel(mCurNotification);
-}
-
-void LLMediaCtrl::onClickIgnore(LLUICtrl* ctrl)
-{
- bool check = ctrl->getValue().asBoolean();
- if (mCurNotification && mCurNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
+ if (response["ok"])
{
- // question was "show again" so invert value to get "ignore"
- check = !check;
+ mMediaSource->getMediaPlugin()->sendAuthResponse(true, response["username"], response["password"]);
+ }
+ else
+ {
+ mMediaSource->getMediaPlugin()->sendAuthResponse(false, "", "");
}
- 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++)
+ delete mWindowShade;
+
+ LLWindowShade::Params params;
+ params.rect = getLocalRect();
+ params.follows.flags = FOLLOWS_ALL;
+ params.notification = notify;
+ //HACK: don't hardcode this
+ if (notify->getName() == "PopupAttempt")
{
- 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;
- }
+ params.bg_image.name = "Yellow_Gradient";
}
+ 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 65dfbbff78..0c369840bf 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -61,7 +61,6 @@ public:
Optional<LLUIColor> caret_color;
Optional<std::string> initial_mime_type;
- Optional<std::string> media_id;
Params();
};
@@ -89,6 +88,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 = "");
@@ -167,9 +167,7 @@ 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);
+ void onAuthSubmit(const LLSD& notification, const LLSD& response);
const S32 mTextureDepthBytes;
LLUUID mMediaTextureID;
@@ -193,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 cf567fb208..b755f6ec17 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -211,9 +211,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/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..be4e23728a 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -293,6 +293,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 +743,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 +763,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);
@@ -1400,6 +1410,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 +1669,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 +1721,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 +1801,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)
@@ -2850,7 +2914,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:
@@ -3003,6 +3066,13 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
plugin->sendPickFileResponse(response);
}
break;
+
+ case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST:
+ {
+ llinfos << "MEDIA_EVENT_AUTH_REQUEST, url " << plugin->getAuthURL() << ", realm " << plugin->getAuthRealm() << LL_ENDL;
+ //plugin->sendAuthResponse(false, "", "");
+ }
+ break;
case LLViewerMediaObserver::MEDIA_EVENT_CLOSE_REQUEST:
{
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 4025a4484f..6f8d12e676 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -155,6 +155,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 +165,7 @@ private:
static LLPluginCookieStore *sCookieStore;
static LLURL sOpenIDURL;
static std::string sOpenIDCookie;
+ static LLPluginClassMedia* sSpareBrowserMediaSource;
};
// Implementation functions not exported into header file
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 03490034d8..c43a5975fd 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7165,6 +7165,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 =
@@ -7915,7 +7921,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 73a37a6993..91a713be56 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"
@@ -102,6 +103,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..3fe5a4dcad 100644
--- a/indra/newview/llweb.h
+++ b/indra/newview/llweb.h
@@ -57,6 +57,10 @@ 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 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/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..97a7a0e737
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_web_content.xml
@@ -0,0 +1,153 @@
+<?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="WEB CONTENT"
+ 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"
+ 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="Stop_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ enabled="false"
+ follows="left|top"
+ height="22"
+ layout="topleft"
+ left="27"
+ 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"
+ follows="left|top"
+ height="22"
+ layout="topleft"
+ left="27"
+ name="reload"
+ top_delta="0"
+ width="22">
+ <button.commit_callback
+ function="WebContent.Reload" />
+ </button>
+ <button
+ image_overlay="Arrow_Right_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ follows="left|top"
+ height="22"
+ layout="topleft"
+ left="51"
+ name="forward"
+ top_delta="0"
+ width="22">
+ <button.commit_callback
+ function="WebContent.Forward" />
+ </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"
+ top_delta="0"
+ width="729">
+ <combo_box.commit_callback
+ function="WebContent.EnterAddress" />
+ </combo_box>
+ </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"
+ 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..2f47d4e201 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -182,6 +182,13 @@
function="Advanced.WebBrowserTest"
parameter="http://join.secondlife.com/"/>
</menu_item_call>
+ <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_separator/>
<menu_item_check
label="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 907f68dc06..9ac811971e 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2629,7 +2629,14 @@
function="Advanced.WebBrowserTest"
parameter="http://secondlife.com/app/search/slurls.html"/>
</menu_item_call>
- <menu_item_call
+ <menu_item_call
+ label="Web Content Browser Test"
+ name="Web Content Browser Test">
+ <menu_item_call.on_click
+ function="Advanced.WebContentTest"
+ parameter="http://secondlife.com/app/search/slurls.html"/>
+ </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 60b876d163..39d623b246 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5009,7 +5009,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>
@@ -5911,7 +5911,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
@@ -5960,8 +5960,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
@@ -5986,7 +5986,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
@@ -6011,7 +6011,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
@@ -6035,7 +6035,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>
@@ -6053,7 +6053,7 @@ We&apos;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>
@@ -6063,7 +6063,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>
@@ -6073,7 +6073,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>
@@ -6083,7 +6083,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>
@@ -6093,7 +6093,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>
@@ -6176,7 +6176,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>
@@ -6186,7 +6186,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>
@@ -6574,6 +6574,23 @@ Mute everyone?
</form>
</notification>
+ <notification
+ name="AuthRequest"
+ type="browser">
+ Enter user name and password to continue.
+ <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 b181ca3bba..1b6c80b376 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -91,6 +91,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" />
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index 873fa23db8..4a2272032b 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -2220,6 +2220,21 @@ void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e
<< ", height = " << self->getGeometryHeight()
<< std::endl;
break;
+
+ case MEDIA_EVENT_AUTH_REQUEST:
+ {
+ //std::cerr << "Media event: MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() ", realm " << self->getAuthRealm() << std::endl;
+
+ // TODO: display an auth dialog
+ self->sendAuthResponse(false, "", "");
+ }
+ break;
+
+ case MEDIA_EVENT_LINK_HOVERED:
+ {
+ std::cerr << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << std::endl;
+ };
+ break;
}
}