summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Palange (Mani) <palange@lindenlab.com>2009-10-01 18:19:45 -0700
committerMark Palange (Mani) <palange@lindenlab.com>2009-10-01 18:19:45 -0700
commitdde2153014cd7d7b8fa704f7067a41344bfbb1c2 (patch)
treef7633ccef179644660897c8bf3684abeda3545f8
parent9b8b0571645f8b607ecc24221c807cc02a03692f (diff)
parent85ea690d47208f6dda020c8ff81021179fbdd0b8 (diff)
merge of latest lindenlab/svn-imports-viewer-20
-rw-r--r--etc/message.xml9
-rw-r--r--indra/linux_updater/linux_updater.cpp4
-rw-r--r--indra/llcommon/lllslconstants.h13
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp58
-rw-r--r--indra/llplugin/llpluginclassmedia.h15
-rw-r--r--indra/llplugin/llpluginmessage.cpp23
-rw-r--r--indra/llplugin/llpluginmessage.h4
-rw-r--r--indra/llplugin/llpluginprocesschild.cpp35
-rw-r--r--indra/llplugin/llpluginprocesschild.h1
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp8
-rw-r--r--indra/llplugin/llpluginprocessparent.h3
-rw-r--r--indra/llprimitive/CMakeLists.txt9
-rw-r--r--indra/llprimitive/llmediaentry.cpp597
-rw-r--r--indra/llprimitive/llmediaentry.h228
-rw-r--r--indra/llprimitive/llprimitive.cpp1
-rw-r--r--indra/llprimitive/lltextureentry.cpp196
-rw-r--r--indra/llprimitive/lltextureentry.h50
-rw-r--r--indra/llprimitive/tests/llmediaentry_test.cpp484
-rw-r--r--indra/llui/CMakeLists.txt4
-rw-r--r--indra/llui/llbutton.cpp45
-rw-r--r--indra/llui/llbutton.h7
-rw-r--r--indra/llui/llcombobox.cpp1
-rw-r--r--indra/llui/lldockablefloater.cpp18
-rw-r--r--indra/llui/lldockcontrol.cpp78
-rw-r--r--indra/llui/lldockcontrol.h10
-rw-r--r--indra/llui/llflatlistview.cpp4
-rw-r--r--indra/llui/llfloater.cpp129
-rw-r--r--indra/llui/llfloater.h14
-rw-r--r--indra/llui/llfocusmgr.cpp42
-rw-r--r--indra/llui/llfocusmgr.h27
-rw-r--r--indra/llui/llhelp.h45
-rw-r--r--indra/llui/llmultisliderctrl.cpp2
-rw-r--r--indra/llui/llpanel.cpp3
-rw-r--r--indra/llui/llpanel.h8
-rw-r--r--indra/llui/llscrollbar.h6
-rw-r--r--indra/llui/llsliderctrl.cpp2
-rw-r--r--indra/llui/llspinctrl.cpp2
-rw-r--r--indra/llui/lltexteditor.cpp43
-rw-r--r--indra/llui/lltexteditor.h10
-rw-r--r--indra/llui/llui.cpp53
-rw-r--r--indra/llui/llui.h7
-rw-r--r--indra/llui/lluictrl.cpp31
-rw-r--r--indra/llui/lluictrl.h11
-rw-r--r--indra/llui/llurlaction.cpp1
-rw-r--r--indra/llui/llview.cpp10
-rw-r--r--indra/llui/llview.h4
-rw-r--r--indra/llvfs/lldir_linux.cpp2
-rw-r--r--indra/llvfs/lldir_mac.cpp2
-rw-r--r--indra/llvfs/lldir_win32.cpp2
-rw-r--r--indra/lscript/lscript_compile/CMakeLists.txt2
-rw-r--r--indra/lscript/lscript_compile/indra.l43
-rw-r--r--indra/lscript/lscript_library/lscript_library.cpp9
-rw-r--r--indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp5
-rw-r--r--indra/media_plugins/quicktime/media_plugin_quicktime.cpp5
-rw-r--r--indra/media_plugins/webkit/media_plugin_webkit.cpp21
-rw-r--r--indra/newview/CMakeLists.txt28
-rw-r--r--indra/newview/app_settings/keywords.ini45
-rw-r--r--indra/newview/app_settings/settings.xml100
-rw-r--r--indra/newview/llappviewer.cpp6
-rw-r--r--indra/newview/llavatarlist.cpp136
-rw-r--r--indra/newview/llavatarlist.h25
-rw-r--r--indra/newview/llbottomtray.cpp5
-rw-r--r--indra/newview/llchannelmanager.cpp54
-rw-r--r--indra/newview/llchannelmanager.h16
-rw-r--r--indra/newview/llchatbar.cpp8
-rw-r--r--indra/newview/llchatbar.h4
-rw-r--r--indra/newview/llchatitemscontainerctrl.cpp392
-rw-r--r--indra/newview/llchatitemscontainerctrl.h86
-rw-r--r--indra/newview/llchatmsgbox.cpp2
-rw-r--r--indra/newview/llchiclet.cpp31
-rw-r--r--indra/newview/llchiclet.h3
-rw-r--r--indra/newview/llcurrencyuimanager.cpp6
-rw-r--r--indra/newview/lldrawable.cpp24
-rw-r--r--indra/newview/lldrawable.h6
-rw-r--r--indra/newview/llface.cpp22
-rw-r--r--indra/newview/llface.h1
-rw-r--r--indra/newview/llfavoritesbar.cpp11
-rw-r--r--indra/newview/llfavoritesbar.h2
-rw-r--r--indra/newview/llfloaterbuycurrency.cpp42
-rw-r--r--indra/newview/llfloaterchat.cpp1
-rw-r--r--indra/newview/llfloaterchatterbox.cpp3
-rw-r--r--indra/newview/llfloaterhelpbrowser.cpp142
-rw-r--r--indra/newview/llfloaterhelpbrowser.h72
-rw-r--r--indra/newview/llfloaterinventory.cpp9
-rw-r--r--indra/newview/llfloaterinventory.h1
-rw-r--r--indra/newview/llfloaterland.cpp2
-rw-r--r--indra/newview/llfloatermediabrowser.cpp76
-rw-r--r--indra/newview/llfloatermediabrowser.h18
-rw-r--r--indra/newview/llfloatermediasettings.cpp249
-rw-r--r--indra/newview/llfloatermediasettings.h81
-rw-r--r--indra/newview/llfloaterpostcard.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp4
-rw-r--r--indra/newview/llfloaterreporter.cpp41
-rw-r--r--indra/newview/llfloaterreporter.h6
-rw-r--r--indra/newview/llfloatertools.cpp683
-rw-r--r--indra/newview/llfloatertools.h19
-rw-r--r--indra/newview/llfloaterurlentry.cpp34
-rw-r--r--indra/newview/llfloaterurlentry.h4
-rw-r--r--indra/newview/llfloaterwhitelistentry.cpp97
-rw-r--r--indra/newview/llfloaterwhitelistentry.h56
-rw-r--r--indra/newview/llfolderview.cpp4
-rw-r--r--indra/newview/llfolderview.h2
-rw-r--r--indra/newview/llgrouplist.cpp49
-rw-r--r--indra/newview/llgrouplist.h24
-rw-r--r--indra/newview/llimfloater.cpp79
-rw-r--r--indra/newview/llimfloater.h6
-rw-r--r--indra/newview/llimhandler.cpp4
-rw-r--r--indra/newview/llimpanel.cpp96
-rw-r--r--indra/newview/llimpanel.h9
-rw-r--r--indra/newview/llimview.cpp246
-rw-r--r--indra/newview/llimview.h67
-rw-r--r--indra/newview/lllandmarkactions.cpp25
-rw-r--r--indra/newview/lllandmarkactions.h9
-rw-r--r--indra/newview/lllocationinputctrl.cpp6
-rw-r--r--indra/newview/llmediactrl.cpp173
-rw-r--r--indra/newview/llmediactrl.h20
-rw-r--r--indra/newview/llnavigationbar.cpp1
-rw-r--r--indra/newview/llnearbychat.cpp29
-rw-r--r--indra/newview/llnearbychat.h6
-rw-r--r--indra/newview/llnearbychatbar.cpp2
-rw-r--r--indra/newview/llnearbychathandler.cpp242
-rw-r--r--indra/newview/llnotificationalerthandler.cpp15
-rw-r--r--indra/newview/llnotificationgrouphandler.cpp5
-rw-r--r--indra/newview/llnotificationhandler.h4
-rw-r--r--indra/newview/llnotificationscripthandler.cpp11
-rw-r--r--indra/newview/llnotificationtiphandler.cpp5
-rw-r--r--indra/newview/lloutputmonitorctrl.cpp8
-rw-r--r--indra/newview/lloutputmonitorctrl.h4
-rw-r--r--indra/newview/llpanelavatar.cpp2
-rw-r--r--indra/newview/llpanelclassified.cpp4
-rw-r--r--indra/newview/llpanelcontents.cpp15
-rw-r--r--indra/newview/llpanelcontents.h18
-rw-r--r--indra/newview/llpanelface.cpp69
-rw-r--r--indra/newview/llpanelface.h9
-rw-r--r--indra/newview/llpanelgroup.cpp15
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp6
-rw-r--r--indra/newview/llpanelgrouproles.cpp2
-rw-r--r--indra/newview/llpanellandmedia.cpp11
-rw-r--r--indra/newview/llpanellandmedia.h9
-rw-r--r--indra/newview/llpanellogin.cpp11
-rw-r--r--indra/newview/llpanellogin.h2
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.cpp409
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.h89
-rw-r--r--indra/newview/llpanelmediasettingspermissions.cpp223
-rw-r--r--indra/newview/llpanelmediasettingspermissions.h71
-rw-r--r--indra/newview/llpanelmediasettingssecurity.cpp233
-rw-r--r--indra/newview/llpanelmediasettingssecurity.h64
-rw-r--r--indra/newview/llpanelpeople.cpp285
-rw-r--r--indra/newview/llpanelpeople.h27
-rw-r--r--indra/newview/llpanelpick.cpp47
-rw-r--r--indra/newview/llpanelpick.h5
-rw-r--r--indra/newview/llpanelpicks.cpp7
-rw-r--r--indra/newview/llpanelpicks.h2
-rw-r--r--indra/newview/llpanelplaces.cpp10
-rw-r--r--indra/newview/llpanelteleporthistory.cpp170
-rw-r--r--indra/newview/llpanelteleporthistory.h26
-rw-r--r--indra/newview/llpreviewscript.cpp104
-rw-r--r--indra/newview/llpreviewscript.h4
-rw-r--r--indra/newview/llscreenchannel.cpp76
-rw-r--r--indra/newview/llscreenchannel.h139
-rw-r--r--indra/newview/llselectmgr.cpp101
-rw-r--r--indra/newview/llselectmgr.h4
-rw-r--r--indra/newview/llsidetray.cpp10
-rw-r--r--indra/newview/llspatialpartition.cpp5
-rw-r--r--indra/newview/llspatialpartition.h1
-rw-r--r--indra/newview/llstartup.cpp11
-rw-r--r--indra/newview/llstatusbar.cpp17
-rw-r--r--indra/newview/llstatusbar.h4
-rw-r--r--indra/newview/llsyswellwindow.cpp44
-rw-r--r--indra/newview/llsyswellwindow.h6
-rw-r--r--indra/newview/lltoast.cpp46
-rw-r--r--indra/newview/lltoast.h10
-rw-r--r--indra/newview/lltoastpanel.h6
-rw-r--r--indra/newview/lltool.cpp16
-rw-r--r--indra/newview/lltoolpie.cpp95
-rw-r--r--indra/newview/lltoolpie.h9
-rw-r--r--indra/newview/llurldispatcher.cpp17
-rw-r--r--indra/newview/llviewerfloaterreg.cpp13
-rw-r--r--indra/newview/llviewerhelp.cpp125
-rw-r--r--indra/newview/llviewerhelp.h65
-rw-r--r--indra/newview/llviewerhelputil.cpp114
-rw-r--r--indra/newview/llviewerhelputil.h49
-rw-r--r--indra/newview/llviewermedia.cpp747
-rw-r--r--indra/newview/llviewermedia.h96
-rw-r--r--indra/newview/llviewermediafocus.cpp41
-rw-r--r--indra/newview/llviewermediafocus.h4
-rw-r--r--indra/newview/llviewermenu.cpp43
-rw-r--r--indra/newview/llviewermenu.h1
-rw-r--r--indra/newview/llviewerobject.cpp107
-rw-r--r--indra/newview/llviewerobject.h16
-rw-r--r--indra/newview/llviewerparcelmedia.cpp17
-rw-r--r--indra/newview/llviewerparcelmgr.cpp1
-rw-r--r--indra/newview/llviewerregion.cpp2
-rw-r--r--indra/newview/llviewertexture.cpp465
-rw-r--r--indra/newview/llviewertexture.h68
-rw-r--r--indra/newview/llviewerwindow.cpp6
-rw-r--r--indra/newview/llvovolume.cpp418
-rw-r--r--indra/newview/llvovolume.h29
-rw-r--r--indra/newview/skins/default/colors.xml14
-rw-r--r--indra/newview/skins/default/html/en-us/help-offline/index.html29
-rw-r--r--indra/newview/skins/default/textures/textures.xml17
-rw-r--r--indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.pngbin0 -> 66186 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.pngbin0 -> 9506 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.pngbin0 -> 2955 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Restore_Press.pngbin0 -> 2971 bytes
-rw-r--r--indra/newview/skins/default/xui/en/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_currency.xml331
-rw-r--r--indra/newview/skins/default/xui/en/floater_help_browser.xml165
-rw-r--r--indra/newview/skins/default/xui/en/floater_media_settings.xml20
-rw-r--r--indra/newview/skins/default/xui/en/floater_sys_well.xml12
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml249
-rw-r--r--indra/newview/skins/default/xui/en/floater_whitelist_entry.xml24
-rw-r--r--indra/newview/skins/default/xui/en/menu_teleport_history_item.xml33
-rw-r--r--indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml19
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml22
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml102
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_media_settings_general.xml199
-rw-r--r--indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml49
-rw-r--r--indra/newview/skins/default/xui/en/panel_media_settings_security.xml56
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_notes.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_view.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_script_ed.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml13
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml797
-rw-r--r--indra/newview/skins/default/xui/en/widgets/scroll_list.xml6
-rw-r--r--indra/newview/skins/default/xui/en/widgets/search_combo_box.xml5
-rw-r--r--indra/newview/tests/llviewerhelputil_test.cpp127
-rwxr-xr-xindra/newview/viewer_manifest.py31
-rw-r--r--install.xml12
238 files changed, 10313 insertions, 3313 deletions
diff --git a/etc/message.xml b/etc/message.xml
index 7ad392d0b5..da08e12aa1 100644
--- a/etc/message.xml
+++ b/etc/message.xml
@@ -671,7 +671,14 @@
<key>UploadBakedTexture</key>
<boolean>true</boolean>
- </map>
+
+ <key>ObjectMedia</key>
+ <boolean>false</boolean>
+
+ <key>ObjectMediaNavigate</key>
+ <boolean>false</boolean>
+
+ </map>
<key>messageBans</key>
<map>
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index 4b0bf6a2d9..d5fee2828e 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -78,9 +78,9 @@ static std::set<std::string> default_trans_args;
void init_default_trans_args()
{
default_trans_args.insert("SECOND_LIFE"); // World
- default_trans_args.insert("SECOND_LIFE_VIEWER");
+ default_trans_args.insert("APP_NAME");
default_trans_args.insert("SECOND_LIFE_GRID");
- default_trans_args.insert("SECOND_LIFE_SUPPORT");
+ default_trans_args.insert("SUPPORT_SITE");
}
bool translate_init(std::string comma_delim_path_list,
diff --git a/indra/llcommon/lllslconstants.h b/indra/llcommon/lllslconstants.h
index a626e3f085..78f4435ed7 100644
--- a/indra/llcommon/lllslconstants.h
+++ b/indra/llcommon/lllslconstants.h
@@ -202,5 +202,18 @@ const U32 CHANGED_OWNER = 0x80;
const U32 CHANGED_REGION = 0x100;
const U32 CHANGED_TELEPORT = 0x200;
const U32 CHANGED_REGION_START = 0x400;
+const U32 CHANGED_MEDIA = 0x800;
+
+// Possible error results
+const U32 LSL_STATUS_OK = 0;
+const U32 LSL_STATUS_MALFORMED_PARAMS = 1000;
+const U32 LSL_STATUS_TYPE_MISMATCH = 1001;
+const U32 LSL_STATUS_BOUNDS_ERROR = 1002;
+const U32 LSL_STATUS_NOT_FOUND = 1003;
+const U32 LSL_STATUS_NOT_SUPPORTED = 1004;
+const U32 LSL_STATUS_INTERNAL_ERROR = 1999;
+
+// Start per-function errors below, starting at 2000:
+const U32 LSL_STATUS_WHITELIST_FAILED = 2001;
#endif
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 54f153d182..7299ede22d 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -99,6 +99,8 @@ void LLPluginClassMedia::reset()
mSetMediaHeight = -1;
mRequestedMediaWidth = 0;
mRequestedMediaHeight = 0;
+ mFullMediaWidth = 0;
+ mFullMediaHeight = 0;
mTextureWidth = 0;
mTextureHeight = 0;
mMediaWidth = 0;
@@ -266,8 +268,16 @@ unsigned char* LLPluginClassMedia::getBitsData()
void LLPluginClassMedia::setSize(int width, int height)
{
- mSetMediaWidth = width;
- mSetMediaHeight = height;
+ if((width > 0) && (height > 0))
+ {
+ mSetMediaWidth = width;
+ mSetMediaHeight = height;
+ }
+ else
+ {
+ mSetMediaWidth = -1;
+ mSetMediaHeight = -1;
+ }
setSizeInternal();
}
@@ -279,16 +289,26 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaWidth = mSetMediaWidth;
mRequestedMediaHeight = mSetMediaHeight;
}
+ else if((mNaturalMediaWidth > 0) && (mNaturalMediaHeight > 0))
+ {
+ mRequestedMediaWidth = mNaturalMediaWidth;
+ mRequestedMediaHeight = mNaturalMediaHeight;
+ }
else
{
mRequestedMediaWidth = mDefaultMediaWidth;
mRequestedMediaHeight = mDefaultMediaHeight;
}
+ // Save these for size/interest calculations
+ mFullMediaWidth = mRequestedMediaWidth;
+ mFullMediaHeight = mRequestedMediaHeight;
+
if(mAllowDownsample)
{
switch(mPriority)
{
+ case PRIORITY_SLIDESHOW:
case PRIORITY_LOW:
// Reduce maximum texture dimension to (or below) mLowPrioritySizeLimit
while((mRequestedMediaWidth > mLowPrioritySizeLimit) || (mRequestedMediaHeight > mLowPrioritySizeLimit))
@@ -309,6 +329,12 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth);
mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
}
+
+ if(mRequestedMediaWidth > 2048)
+ mRequestedMediaWidth = 2048;
+
+ if(mRequestedMediaHeight > 2048)
+ mRequestedMediaHeight = 2048;
}
void LLPluginClassMedia::setAutoScale(bool auto_scale)
@@ -519,6 +545,10 @@ void LLPluginClassMedia::setPriority(EPriority priority)
std::string priority_string;
switch(priority)
{
+ case PRIORITY_UNLOADED:
+ priority_string = "unloaded";
+ mSleepTime = 1.0f;
+ break;
case PRIORITY_STOPPED:
priority_string = "stopped";
mSleepTime = 1.0f;
@@ -527,6 +557,10 @@ void LLPluginClassMedia::setPriority(EPriority priority)
priority_string = "hidden";
mSleepTime = 1.0f;
break;
+ case PRIORITY_SLIDESHOW:
+ priority_string = "slideshow";
+ mSleepTime = 1.0f;
+ break;
case PRIORITY_LOW:
priority_string = "low";
mSleepTime = 1.0f / 50.0f;
@@ -550,6 +584,8 @@ void LLPluginClassMedia::setPriority(EPriority priority)
mPlugin->setSleepTime(mSleepTime);
}
+ LL_DEBUGS("PluginPriority") << this << ": setting priority to " << priority_string << LL_ENDL;
+
// This may affect the calculated size, so recalculate it here.
setSizeInternal();
}
@@ -557,15 +593,27 @@ void LLPluginClassMedia::setPriority(EPriority priority)
void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
{
- if(mLowPrioritySizeLimit != size)
+ int power = nextPowerOf2(size);
+ if(mLowPrioritySizeLimit != power)
{
- mLowPrioritySizeLimit = size;
+ mLowPrioritySizeLimit = power;
// This may affect the calculated size, so recalculate it here.
setSizeInternal();
}
}
+F64 LLPluginClassMedia::getCPUUsage()
+{
+ F64 result = 0.0f;
+
+ if(mPlugin)
+ {
+ result = mPlugin->getCPUUsage();
+ }
+
+ return result;
+}
void LLPluginClassMedia::cut()
{
@@ -722,7 +770,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mNaturalMediaWidth = width;
mNaturalMediaHeight = height;
- setSize(width, height);
+ setSizeInternal();
}
else if(message_name == "size_change_response")
{
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 665a423d07..331ca5f6dc 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -66,6 +66,8 @@ public:
int getBitsHeight() const { return (mTextureHeight > 0) ? mTextureHeight : 0; };
int getTextureWidth() const;
int getTextureHeight() const;
+ int getFullWidth() const { return mFullMediaWidth; };
+ int getFullHeight() const { return mFullMediaHeight; };
// This may return NULL. Callers need to check for and handle this case.
unsigned char* getBitsData();
@@ -138,9 +140,11 @@ public:
typedef enum
{
+ PRIORITY_UNLOADED, // media plugin isn't even loaded.
PRIORITY_STOPPED, // media is not playing, shouldn't need to update at all.
PRIORITY_HIDDEN, // media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc.
- PRIORITY_LOW, // media is in the far distance, may be rendered at reduced size
+ PRIORITY_SLIDESHOW, // media is in the far distance, updates very infrequently
+ PRIORITY_LOW, // media is in the distance, may be rendered at reduced size
PRIORITY_NORMAL, // normal (default) priority
PRIORITY_HIGH // media has user focus and/or is taking up most of the screen
}EPriority;
@@ -148,6 +152,8 @@ public:
void setPriority(EPriority priority);
void setLowPrioritySizeLimit(int size);
+ F64 getCPUUsage();
+
// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
std::string getCursorName() const { return mCursorName; };
@@ -230,6 +236,7 @@ public:
void initializeUrlHistory(const LLSD& url_history);
protected:
+
LLPluginClassMediaOwner *mOwner;
// Notify this object's owner that an event has occurred.
@@ -266,7 +273,11 @@ protected:
int mSetMediaWidth;
int mSetMediaHeight;
- // Actual media size being set (may be affected by auto-scale)
+ // Full calculated media size (before auto-scale and downsample calculations)
+ int mFullMediaWidth;
+ int mFullMediaHeight;
+
+ // Actual media size being set (after auto-scale)
int mRequestedMediaWidth;
int mRequestedMediaHeight;
diff --git a/indra/llplugin/llpluginmessage.cpp b/indra/llplugin/llpluginmessage.cpp
index bfabc5b7ca..e7412a1d8f 100644
--- a/indra/llplugin/llpluginmessage.cpp
+++ b/indra/llplugin/llpluginmessage.cpp
@@ -33,6 +33,7 @@
#include "llpluginmessage.h"
#include "llsdserialize.h"
+#include "u64.h"
LLPluginMessage::LLPluginMessage()
{
@@ -93,6 +94,14 @@ void LLPluginMessage::setValueReal(const std::string &key, F64 value)
mMessage["params"][key] = value;
}
+void LLPluginMessage::setValuePointer(const std::string &key, void* value)
+{
+ std::stringstream temp;
+ // iostreams should output pointer values in hex with an initial 0x by default.
+ temp << value;
+ setValue(key, temp.str());
+}
+
std::string LLPluginMessage::getClass(void) const
{
return mMessage["class"];
@@ -189,6 +198,20 @@ F64 LLPluginMessage::getValueReal(const std::string &key) const
return result;
}
+void* LLPluginMessage::getValuePointer(const std::string &key) const
+{
+ void* result = NULL;
+
+ if(mMessage["params"].has(key))
+ {
+ std::string value = mMessage["params"][key].asString();
+
+ result = (void*)llstrtou64(value.c_str(), NULL, 16);
+ }
+
+ return result;
+}
+
std::string LLPluginMessage::generate(void) const
{
std::ostringstream result;
diff --git a/indra/llplugin/llpluginmessage.h b/indra/llplugin/llpluginmessage.h
index a17ec4bb98..f1a0e7c624 100644
--- a/indra/llplugin/llpluginmessage.h
+++ b/indra/llplugin/llpluginmessage.h
@@ -57,6 +57,7 @@ public:
void setValueU32(const std::string &key, U32 value);
void setValueBoolean(const std::string &key, bool value);
void setValueReal(const std::string &key, F64 value);
+ void setValuePointer(const std::string &key, void *value);
std::string getClass(void) const;
std::string getName(void) const;
@@ -82,6 +83,9 @@ public:
// get the value of a key as a float.
F64 getValueReal(const std::string &key) const;
+ // get the value of a key as a pointer.
+ void* getValuePointer(const std::string &key) const;
+
// Flatten the message into a string
std::string generate(void) const;
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index dc51671032..450dcb3c78 100644
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -43,6 +43,7 @@ LLPluginProcessChild::LLPluginProcessChild()
mInstance = NULL;
mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
mSleepTime = 1.0f / 100.0f; // default: send idle messages at 100Hz
+ mCPUElapsed = 0.0f;
}
LLPluginProcessChild::~LLPluginProcessChild()
@@ -130,6 +131,7 @@ void LLPluginProcessChild::idle(void)
{
mHeartbeat.start();
mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
+ mCPUElapsed = 0.0f;
setState(STATE_PLUGIN_LOADED);
}
else
@@ -158,10 +160,22 @@ void LLPluginProcessChild::idle(void)
mInstance->idle();
- if(mHeartbeat.checkExpirationAndReset(HEARTBEAT_SECONDS))
+ if(mHeartbeat.hasExpired())
{
+
// This just proves that we're not stuck down inside the plugin code.
- sendMessageToParent(LLPluginMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat"));
+ LLPluginMessage heartbeat(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat");
+
+ // Calculate the approximage CPU usage fraction (floating point value between 0 and 1) used by the plugin this heartbeat cycle.
+ // Note that this will not take into account any threads or additional processes the plugin spawns, but it's a first approximation.
+ // If we could write OS-specific functions to query the actual CPU usage of this process, that would be a better approximation.
+ heartbeat.setValueReal("cpu_usage", mCPUElapsed / mHeartbeat.getElapsedTimeF64());
+
+ sendMessageToParent(heartbeat);
+
+ mHeartbeat.reset();
+ mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
+ mCPUElapsed = 0.0f;
}
}
// receivePluginMessage will transition to STATE_UNLOADING
@@ -253,8 +267,11 @@ void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
std::string buffer = message.generate();
LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL;
-
+ LLTimer elapsed;
+
mInstance->sendMessage(buffer);
+
+ mCPUElapsed += elapsed.getElapsedTimeF64();
}
void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message)
@@ -317,12 +334,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
LLPluginMessage message("base", "shm_added");
message.setValue("name", name);
message.setValueS32("size", (S32)size);
- // shm address is split into 2x32bit values because LLSD doesn't serialize 64bit values and we need to support 64-bit addressing.
- void * address = region->getMappedAddress();
- U32 address_lo = (U32)(U64(address) & 0xFFFFFFFF); // Extract the lower 32 bits
- U32 address_hi = (U32)((U64(address)>>32) & 0xFFFFFFFF); // Extract the higher 32 bits
- message.setValueU32("address", address_lo);
- message.setValueU32("address_1", address_hi);
+ message.setValuePointer("address", region->getMappedAddress());
sendMessageToPlugin(message);
// and send the response to the parent
@@ -380,7 +392,11 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
if(passMessage && mInstance != NULL)
{
+ LLTimer elapsed;
+
mInstance->sendMessage(message);
+
+ mCPUElapsed += elapsed.getElapsedTimeF64();
}
}
@@ -454,6 +470,7 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
if(passMessage)
{
+ LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL;
writeMessageRaw(message);
}
}
diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h
index f92905e8bd..75860bdf0a 100644
--- a/indra/llplugin/llpluginprocesschild.h
+++ b/indra/llplugin/llpluginprocesschild.h
@@ -102,6 +102,7 @@ private:
LLTimer mHeartbeat;
F64 mSleepTime;
+ F64 mCPUElapsed;
};
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index f18a117dde..41784a713c 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -38,7 +38,7 @@
#include "llapr.h"
// If we don't receive a heartbeat in this many seconds, we declare the plugin locked up.
-static const F32 PLUGIN_LOCKED_UP_SECONDS = 10.0f;
+static const F32 PLUGIN_LOCKED_UP_SECONDS = 15.0f;
// Somewhat longer timeout for initial launch.
static const F32 PLUGIN_LAUNCH_SECONDS = 20.0f;
@@ -87,6 +87,7 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
{
mProcess.setExecutable(launcher_filename);
mPluginFile = plugin_filename;
+ mCPUUsage = 0.0f;
setState(STATE_INITIALIZED);
}
@@ -503,6 +504,11 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
{
// this resets our timer.
mHeartbeat.setTimerExpirySec(PLUGIN_LOCKED_UP_SECONDS);
+
+ mCPUUsage = message.getValueReal("cpu_usage");
+
+ LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL;
+
}
else if(message_name == "shm_add_response")
{
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index 545eb85c9a..0d0b047c88 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -96,6 +96,8 @@ public:
bool getDisableTimeout() { return mDisableTimeout; };
void setDisableTimeout(bool disable) { mDisableTimeout = disable; };
+ F64 getCPUUsage() { return mCPUUsage; };
+
private:
enum EState
@@ -140,6 +142,7 @@ private:
LLTimer mHeartbeat;
F64 mSleepTime;
+ F64 mCPUUsage;
bool mDisableTimeout;
};
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 478dd398ff..d130513637 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -17,6 +17,7 @@ include_directories(
set(llprimitive_SOURCE_FILES
llmaterialtable.cpp
+ llmediaentry.cpp
llprimitive.cpp
llprimtexturelist.cpp
lltextureanim.cpp
@@ -31,6 +32,7 @@ set(llprimitive_HEADER_FILES
legacy_object_types.h
llmaterialtable.h
+ llmediaentry.h
llprimitive.h
llprimtexturelist.h
lltextureanim.h
@@ -49,3 +51,10 @@ set_source_files_properties(${llprimitive_HEADER_FILES}
list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
add_library (llprimitive ${llprimitive_SOURCE_FILES})
+
+#add unit tests
+INCLUDE(LLAddBuildTest)
+SET(llprimitive_TEST_SOURCE_FILES
+ llmediaentry.cpp
+ )
+LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}")
diff --git a/indra/llprimitive/llmediaentry.cpp b/indra/llprimitive/llmediaentry.cpp
new file mode 100644
index 0000000000..fa04bf80e7
--- /dev/null
+++ b/indra/llprimitive/llmediaentry.cpp
@@ -0,0 +1,597 @@
+/**
+ * @file llmediaentry.cpp
+ * @brief This is a single instance of media data related to the face of a prim
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llmediaentry.h"
+#include "lllslconstants.h"
+
+#include <boost/regex.hpp>
+
+// LLSD key defines
+// DO NOT REORDER OR REMOVE THESE!
+
+// Some LLSD keys. Do not change!
+#define MEDIA_ALT_IMAGE_ENABLE_KEY_STR "alt_image_enable"
+#define MEDIA_CONTROLS_KEY_STR "controls"
+#define MEDIA_CURRENT_URL_KEY_STR "current_url"
+#define MEDIA_HOME_URL_KEY_STR "home_url"
+#define MEDIA_AUTO_LOOP_KEY_STR "auto_loop"
+#define MEDIA_AUTO_PLAY_KEY_STR "auto_play"
+#define MEDIA_AUTO_SCALE_KEY_STR "auto_scale"
+#define MEDIA_AUTO_ZOOM_KEY_STR "auto_zoom"
+#define MEDIA_FIRST_CLICK_INTERACT_KEY_STR "first_click_interact"
+#define MEDIA_WIDTH_PIXELS_KEY_STR "width_pixels"
+#define MEDIA_HEIGHT_PIXELS_KEY_STR "height_pixels"
+
+// "security" fields
+#define MEDIA_WHITELIST_ENABLE_KEY_STR "whitelist_enable"
+#define MEDIA_WHITELIST_KEY_STR "whitelist"
+
+// "permissions" fields
+#define MEDIA_PERMS_INTERACT_KEY_STR "perms_interact"
+#define MEDIA_PERMS_CONTROL_KEY_STR "perms_control"
+
+// "general" fields
+const char* LLMediaEntry::ALT_IMAGE_ENABLE_KEY = MEDIA_ALT_IMAGE_ENABLE_KEY_STR;
+const char* LLMediaEntry::CONTROLS_KEY = MEDIA_CONTROLS_KEY_STR;
+const char* LLMediaEntry::CURRENT_URL_KEY = MEDIA_CURRENT_URL_KEY_STR;
+const char* LLMediaEntry::HOME_URL_KEY = MEDIA_HOME_URL_KEY_STR;
+const char* LLMediaEntry::AUTO_LOOP_KEY = MEDIA_AUTO_LOOP_KEY_STR;
+const char* LLMediaEntry::AUTO_PLAY_KEY = MEDIA_AUTO_PLAY_KEY_STR;
+const char* LLMediaEntry::AUTO_SCALE_KEY = MEDIA_AUTO_SCALE_KEY_STR;
+const char* LLMediaEntry::AUTO_ZOOM_KEY = MEDIA_AUTO_ZOOM_KEY_STR;
+const char* LLMediaEntry::FIRST_CLICK_INTERACT_KEY = MEDIA_FIRST_CLICK_INTERACT_KEY_STR;
+const char* LLMediaEntry::WIDTH_PIXELS_KEY = MEDIA_WIDTH_PIXELS_KEY_STR;
+const char* LLMediaEntry::HEIGHT_PIXELS_KEY = MEDIA_HEIGHT_PIXELS_KEY_STR;
+
+// "security" fields
+const char* LLMediaEntry::WHITELIST_ENABLE_KEY = MEDIA_WHITELIST_ENABLE_KEY_STR;
+const char* LLMediaEntry::WHITELIST_KEY = MEDIA_WHITELIST_KEY_STR;
+
+// "permissions" fields
+const char* LLMediaEntry::PERMS_INTERACT_KEY = MEDIA_PERMS_INTERACT_KEY_STR;
+const char* LLMediaEntry::PERMS_CONTROL_KEY = MEDIA_PERMS_CONTROL_KEY_STR;
+
+#define DEFAULT_URL_PREFIX "http://"
+
+// Constructor(s)
+LLMediaEntry::LLMediaEntry() :
+ mAltImageEnable(false),
+ mControls(STANDARD),
+ mCurrentURL(""),
+ mHomeURL(""),
+ mAutoLoop(false),
+ mAutoPlay(false),
+ mAutoScale(false),
+ mAutoZoom(false),
+ mFirstClickInteract(false),
+ mWidthPixels(0),
+ mHeightPixels(0),
+ mWhiteListEnable(false),
+ // mWhiteList
+ mPermsInteract(PERM_ALL),
+ mPermsControl(PERM_ALL),
+ mMediaIDp(NULL)
+{
+}
+
+LLMediaEntry::LLMediaEntry(const LLMediaEntry &rhs) :
+ mMediaIDp(NULL)
+{
+ // "general" fields
+ mAltImageEnable = rhs.mAltImageEnable;
+ mControls = rhs.mControls;
+ mCurrentURL = rhs.mCurrentURL;
+ mHomeURL = rhs.mHomeURL;
+ mAutoLoop = rhs.mAutoLoop;
+ mAutoPlay = rhs.mAutoPlay;
+ mAutoScale = rhs.mAutoScale;
+ mAutoZoom = rhs.mAutoZoom;
+ mFirstClickInteract = rhs.mFirstClickInteract;
+ mWidthPixels = rhs.mWidthPixels;
+ mHeightPixels = rhs.mHeightPixels;
+
+ // "security" fields
+ mWhiteListEnable = rhs.mWhiteListEnable;
+ mWhiteList = rhs.mWhiteList;
+
+ // "permissions" fields
+ mPermsInteract = rhs.mPermsInteract;
+ mPermsControl = rhs.mPermsControl;
+}
+
+LLMediaEntry::~LLMediaEntry()
+{
+ if (NULL != mMediaIDp)
+ {
+ delete mMediaIDp;
+ }
+}
+
+LLSD LLMediaEntry::asLLSD() const
+{
+ LLSD sd;
+ asLLSD(sd);
+ return sd;
+}
+
+//
+// LLSD functions
+//
+void LLMediaEntry::asLLSD(LLSD& sd) const
+{
+ // "general" fields
+ sd[ALT_IMAGE_ENABLE_KEY] = mAltImageEnable;
+ sd[CONTROLS_KEY] = (LLSD::Integer)mControls;
+ sd[CURRENT_URL_KEY] = mCurrentURL;
+ sd[HOME_URL_KEY] = mHomeURL;
+ sd[AUTO_LOOP_KEY] = mAutoLoop;
+ sd[AUTO_PLAY_KEY] = mAutoPlay;
+ sd[AUTO_SCALE_KEY] = mAutoScale;
+ sd[AUTO_ZOOM_KEY] = mAutoZoom;
+ sd[FIRST_CLICK_INTERACT_KEY] = mFirstClickInteract;
+ sd[WIDTH_PIXELS_KEY] = mWidthPixels;
+ sd[HEIGHT_PIXELS_KEY] = mHeightPixels;
+
+ // "security" fields
+ sd[WHITELIST_ENABLE_KEY] = mWhiteListEnable;
+ for (U32 i=0; i<mWhiteList.size(); i++)
+ {
+ sd[WHITELIST_KEY].append(mWhiteList[i]);
+ }
+
+ // "permissions" fields
+ sd[PERMS_INTERACT_KEY] = mPermsInteract;
+ sd[PERMS_CONTROL_KEY] = mPermsControl;
+}
+
+// static
+bool LLMediaEntry::checkLLSD(const LLSD& sd)
+{
+ if (sd.isUndefined()) return true;
+ LLMediaEntry temp;
+ return temp.fromLLSDInternal(sd, true);
+}
+
+void LLMediaEntry::fromLLSD(const LLSD& sd)
+{
+ (void)fromLLSDInternal(sd, true);
+}
+
+void LLMediaEntry::mergeFromLLSD(const LLSD& sd)
+{
+ (void)fromLLSDInternal(sd, false);
+}
+
+// *NOTE: returns true if NO failures to set occurred, false otherwise.
+// However, be aware that if a failure to set does occur, it does
+// not stop setting fields from the LLSD!
+bool LLMediaEntry::fromLLSDInternal(const LLSD& sd, bool overwrite)
+{
+ // *HACK: we sort of cheat here and assume that status is a
+ // bit field. We "or" into status and instead of returning
+ // it, we return whether it finishes off as LSL_STATUS_OK or not.
+ U32 status = LSL_STATUS_OK;
+
+ // "general" fields
+ if ( overwrite || sd.has(ALT_IMAGE_ENABLE_KEY) )
+ {
+ status |= setAltImageEnable( sd[ALT_IMAGE_ENABLE_KEY] );
+ }
+ if ( overwrite || sd.has(CONTROLS_KEY) )
+ {
+ status |= setControls( (MediaControls)(LLSD::Integer)sd[CONTROLS_KEY] );
+ }
+ if ( overwrite || sd.has(CURRENT_URL_KEY) )
+ {
+ // Don't check whitelist
+ status |= setCurrentURLInternal( sd[CURRENT_URL_KEY], false );
+ }
+ if ( overwrite || sd.has(HOME_URL_KEY) )
+ {
+ status |= setHomeURL( sd[HOME_URL_KEY] );
+ }
+ if ( overwrite || sd.has(AUTO_LOOP_KEY) )
+ {
+ status |= setAutoLoop( sd[AUTO_LOOP_KEY] );
+ }
+ if ( overwrite || sd.has(AUTO_PLAY_KEY) )
+ {
+ status |= setAutoPlay( sd[AUTO_PLAY_KEY] );
+ }
+ if ( overwrite || sd.has(AUTO_SCALE_KEY) )
+ {
+ status |= setAutoScale( sd[AUTO_SCALE_KEY] );
+ }
+ if ( overwrite || sd.has(AUTO_ZOOM_KEY) )
+ {
+ status |= setAutoZoom( sd[AUTO_ZOOM_KEY] );
+ }
+ if ( overwrite || sd.has(FIRST_CLICK_INTERACT_KEY) )
+ {
+ status |= setFirstClickInteract( sd[FIRST_CLICK_INTERACT_KEY] );
+ }
+ if ( overwrite || sd.has(WIDTH_PIXELS_KEY) )
+ {
+ status |= setWidthPixels( (LLSD::Integer)sd[WIDTH_PIXELS_KEY] );
+ }
+ if ( overwrite || sd.has(HEIGHT_PIXELS_KEY) )
+ {
+ status |= setHeightPixels( (LLSD::Integer)sd[HEIGHT_PIXELS_KEY] );
+ }
+
+ // "security" fields
+ if ( overwrite || sd.has(WHITELIST_ENABLE_KEY) )
+ {
+ status |= setWhiteListEnable( sd[WHITELIST_ENABLE_KEY] );
+ }
+ if ( overwrite || sd.has(WHITELIST_KEY) )
+ {
+ status |= setWhiteList( sd[WHITELIST_KEY] );
+ }
+
+ // "permissions" fields
+ if ( overwrite || sd.has(PERMS_INTERACT_KEY) )
+ {
+ status |= setPermsInteract( 0xff & (LLSD::Integer)sd[PERMS_INTERACT_KEY] );
+ }
+ if ( overwrite || sd.has(PERMS_CONTROL_KEY) )
+ {
+ status |= setPermsControl( 0xff & (LLSD::Integer)sd[PERMS_CONTROL_KEY] );
+ }
+
+ return LSL_STATUS_OK == status;
+}
+
+LLMediaEntry& LLMediaEntry::operator=(const LLMediaEntry &rhs)
+{
+ if (this != &rhs)
+ {
+ // "general" fields
+ mAltImageEnable = rhs.mAltImageEnable;
+ mControls = rhs.mControls;
+ mCurrentURL = rhs.mCurrentURL;
+ mHomeURL = rhs.mHomeURL;
+ mAutoLoop = rhs.mAutoLoop;
+ mAutoPlay = rhs.mAutoPlay;
+ mAutoScale = rhs.mAutoScale;
+ mAutoZoom = rhs.mAutoZoom;
+ mFirstClickInteract = rhs.mFirstClickInteract;
+ mWidthPixels = rhs.mWidthPixels;
+ mHeightPixels = rhs.mHeightPixels;
+
+ // "security" fields
+ mWhiteListEnable = rhs.mWhiteListEnable;
+ mWhiteList = rhs.mWhiteList;
+
+ // "permissions" fields
+ mPermsInteract = rhs.mPermsInteract;
+ mPermsControl = rhs.mPermsControl;
+ }
+
+ return *this;
+}
+
+bool LLMediaEntry::operator==(const LLMediaEntry &rhs) const
+{
+ return (
+ // "general" fields
+ mAltImageEnable == rhs.mAltImageEnable &&
+ mControls == rhs.mControls &&
+ mCurrentURL == rhs.mCurrentURL &&
+ mHomeURL == rhs.mHomeURL &&
+ mAutoLoop == rhs.mAutoLoop &&
+ mAutoPlay == rhs.mAutoPlay &&
+ mAutoScale == rhs.mAutoScale &&
+ mAutoZoom == rhs.mAutoZoom &&
+ mFirstClickInteract == rhs.mFirstClickInteract &&
+ mWidthPixels == rhs.mWidthPixels &&
+ mHeightPixels == rhs.mHeightPixels &&
+
+ // "security" fields
+ mWhiteListEnable == rhs.mWhiteListEnable &&
+ mWhiteList == rhs.mWhiteList &&
+
+ // "permissions" fields
+ mPermsInteract == rhs.mPermsInteract &&
+ mPermsControl == rhs.mPermsControl
+
+ );
+}
+
+bool LLMediaEntry::operator!=(const LLMediaEntry &rhs) const
+{
+ return (
+ // "general" fields
+ mAltImageEnable != rhs.mAltImageEnable ||
+ mControls != rhs.mControls ||
+ mCurrentURL != rhs.mCurrentURL ||
+ mHomeURL != rhs.mHomeURL ||
+ mAutoLoop != rhs.mAutoLoop ||
+ mAutoPlay != rhs.mAutoPlay ||
+ mAutoScale != rhs.mAutoScale ||
+ mAutoZoom != rhs.mAutoZoom ||
+ mFirstClickInteract != rhs.mFirstClickInteract ||
+ mWidthPixels != rhs.mWidthPixels ||
+ mHeightPixels != rhs.mHeightPixels ||
+
+ // "security" fields
+ mWhiteListEnable != rhs.mWhiteListEnable ||
+ mWhiteList != rhs.mWhiteList ||
+
+ // "permissions" fields
+ mPermsInteract != rhs.mPermsInteract ||
+ mPermsControl != rhs.mPermsControl
+
+ );
+}
+
+U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist )
+{
+ // *NOTE: This code is VERY similar to the setWhitelist below.
+ // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
+ U32 size = 0;
+ U32 count = 0;
+ // First count to make sure the size constraint is not violated
+ std::vector<std::string>::const_iterator iter = whitelist.begin();
+ std::vector<std::string>::const_iterator end = whitelist.end();
+ for ( ; iter < end; ++iter)
+ {
+ const std::string &entry = (*iter);
+ size += entry.length() + 1; // Include one for \0
+ count ++;
+ if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT)
+ {
+ return LSL_STATUS_BOUNDS_ERROR;
+ }
+ }
+ // Next clear the vector
+ mWhiteList.clear();
+ // Then re-iterate and copy entries
+ iter = whitelist.begin();
+ for ( ; iter < end; ++iter)
+ {
+ const std::string &entry = (*iter);
+ mWhiteList.push_back(entry);
+ }
+ return LSL_STATUS_OK;
+}
+
+U32 LLMediaEntry::setWhiteList( const LLSD &whitelist )
+{
+ // If whitelist is undef, this is a no-op.
+ if (whitelist.isUndefined()) return LSL_STATUS_OK;
+
+ // However, if the whitelist is an empty array, erase it.
+ if (whitelist.isArray())
+ {
+ // *NOTE: This code is VERY similar to the setWhitelist above.
+ // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
+ U32 size = 0;
+ U32 count = 0;
+ // First check to make sure the size and count constraints are not violated
+ LLSD::array_const_iterator iter = whitelist.beginArray();
+ LLSD::array_const_iterator end = whitelist.endArray();
+ for ( ; iter < end; ++iter)
+ {
+ const std::string &entry = (*iter).asString();
+ size += entry.length() + 1; // Include one for \0
+ count ++;
+ if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT)
+ {
+ return LSL_STATUS_BOUNDS_ERROR;
+ }
+ }
+ // Next clear the vector
+ mWhiteList.clear();
+ // Then re-iterate and copy entries
+ iter = whitelist.beginArray();
+ for ( ; iter < end; ++iter)
+ {
+ const std::string &entry = (*iter).asString();
+ mWhiteList.push_back(entry);
+ }
+ return LSL_STATUS_OK;
+ }
+ else
+ {
+ return LSL_STATUS_MALFORMED_PARAMS;
+ }
+}
+
+
+static void prefix_with(std::string &str, const char *chars, const char *prefix)
+{
+ // Given string 'str', prefix all instances of any character in 'chars'
+ // with 'prefix'
+ size_t found = str.find_first_of(chars);
+ size_t prefix_len = strlen(prefix);
+ while (found != std::string::npos)
+ {
+ str.insert(found, prefix, prefix_len);
+ found = str.find_first_of(chars, found+prefix_len+1);
+ }
+}
+
+static bool pattern_match(const std::string &candidate_str, const std::string &pattern)
+{
+ // If the pattern is empty, it matches
+ if (pattern.empty()) return true;
+
+ // 'pattern' is a glob pattern, we only accept '*' chars
+ // copy it
+ std::string expression = pattern;
+
+ // Escape perl's regexp chars with a backslash, except all "*" chars
+ prefix_with(expression, ".[{()\\+?|^$", "\\");
+ prefix_with(expression, "*", ".");
+
+ // case-insensitive matching:
+ boost::regex regexp(expression, boost::regex::perl|boost::regex::icase);
+ return boost::regex_match(candidate_str, regexp);
+}
+
+bool LLMediaEntry::checkCandidateUrl(const std::string& url) const
+{
+ if (getWhiteListEnable())
+ {
+ return checkUrlAgainstWhitelist(url, getWhiteList());
+ }
+ else
+ {
+ return true;
+ }
+}
+
+// static
+bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url,
+ const std::vector<std::string> &whitelist)
+{
+ bool passes = true;
+ // *NOTE: no entries? Don't check
+ if (whitelist.size() > 0)
+ {
+ passes = false;
+
+ // Case insensitive: the reason why we toUpper both this and the
+ // filter
+ std::string candidate_url = url;
+ // Use lluri to see if there is a path part in the candidate URL. No path? Assume "/"
+ LLURI candidate_uri(candidate_url);
+ std::vector<std::string>::const_iterator iter = whitelist.begin();
+ std::vector<std::string>::const_iterator end = whitelist.end();
+ for ( ; iter < end; ++iter )
+ {
+ std::string filter = *iter;
+
+ LLURI filter_uri(filter);
+ bool scheme_passes = pattern_match( candidate_uri.scheme(), filter_uri.scheme() );
+ if (filter_uri.scheme().empty())
+ {
+ filter_uri = LLURI(DEFAULT_URL_PREFIX + filter);
+ }
+ bool authority_passes = pattern_match( candidate_uri.authority(), filter_uri.authority() );
+ bool path_passes = pattern_match( candidate_uri.escapedPath(), filter_uri.escapedPath() );
+
+ if (scheme_passes && authority_passes && path_passes)
+ {
+ passes = true;
+ break;
+ }
+ }
+ }
+ return passes;
+}
+
+U32 LLMediaEntry::setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit )
+{
+ if ( value.length() > limit )
+ {
+ return LSL_STATUS_BOUNDS_ERROR;
+ }
+ else
+ {
+ field = value;
+ return LSL_STATUS_OK;
+ }
+}
+
+U32 LLMediaEntry::setControls(LLMediaEntry::MediaControls controls)
+{
+ if (controls == STANDARD ||
+ controls == MINI)
+ {
+ mControls = controls;
+ return LSL_STATUS_OK;
+ }
+ return LSL_STATUS_BOUNDS_ERROR;
+}
+
+U32 LLMediaEntry::setPermsInteract( U8 val )
+{
+ mPermsInteract = val & PERM_MASK;
+ return LSL_STATUS_OK;
+}
+
+U32 LLMediaEntry::setPermsControl( U8 val )
+{
+ mPermsControl = val & PERM_MASK;
+ return LSL_STATUS_OK;
+}
+
+U32 LLMediaEntry::setCurrentURL(const std::string& current_url)
+{
+ return setCurrentURLInternal( current_url, true );
+}
+
+U32 LLMediaEntry::setCurrentURLInternal(const std::string& current_url, bool check_whitelist)
+{
+ if ( ! check_whitelist || checkCandidateUrl(current_url))
+ {
+ return setStringFieldWithLimit( mCurrentURL, current_url, MAX_URL_LENGTH );
+ }
+ else
+ {
+ return LSL_STATUS_WHITELIST_FAILED;
+ }
+}
+
+U32 LLMediaEntry::setHomeURL(const std::string& home_url)
+{
+ return setStringFieldWithLimit( mHomeURL, home_url, MAX_URL_LENGTH );
+}
+
+U32 LLMediaEntry::setWidthPixels(U16 width)
+{
+ if (width > MAX_WIDTH_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
+ mWidthPixels = width;
+ return LSL_STATUS_OK;
+}
+
+U32 LLMediaEntry::setHeightPixels(U16 height)
+{
+ if (height > MAX_HEIGHT_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
+ mHeightPixels = height;
+ return LSL_STATUS_OK;
+}
+
+const LLUUID &LLMediaEntry::getMediaID() const
+{
+ // Lazily generate media ID
+ if (NULL == mMediaIDp)
+ {
+ mMediaIDp = new LLUUID();
+ mMediaIDp->generate();
+ }
+ return *mMediaIDp;
+}
+
diff --git a/indra/llprimitive/llmediaentry.h b/indra/llprimitive/llmediaentry.h
new file mode 100644
index 0000000000..2a5486666a
--- /dev/null
+++ b/indra/llprimitive/llmediaentry.h
@@ -0,0 +1,228 @@
+/**
+ * @file llmediaentry.h
+ * @brief This is a single instance of media data related to the face of a prim
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMEDIAENTRY_H
+#define LL_LLMEDIAENTRY_H
+
+#include "llsd.h"
+#include "llstring.h"
+
+// For return values of set*
+#include "lllslconstants.h"
+
+class LLMediaEntry
+{
+public:
+ enum MediaControls {
+ STANDARD = 0,
+ MINI
+ };
+
+ // Constructors
+ LLMediaEntry();
+ LLMediaEntry(const LLMediaEntry &rhs);
+
+ LLMediaEntry &operator=(const LLMediaEntry &rhs);
+ virtual ~LLMediaEntry();
+
+ bool operator==(const LLMediaEntry &rhs) const;
+ bool operator!=(const LLMediaEntry &rhs) const;
+
+ // Render as LLSD
+ LLSD asLLSD() const;
+ void asLLSD(LLSD& sd) const;
+ operator LLSD() const { return asLLSD(); }
+ // Returns false iff the given LLSD contains fields that violate any bounds
+ // limits.
+ static bool checkLLSD(const LLSD& sd);
+ // This doesn't merge, it overwrites the data, so will use
+ // LLSD defaults if need be. Note: does not check limits!
+ // Use checkLLSD() above first to ensure the LLSD is valid.
+ void fromLLSD(const LLSD& sd);
+ // This merges data from the incoming LLSD into our fields.
+ // Note that it also does NOT check limits! Use checkLLSD() above first.
+ void mergeFromLLSD(const LLSD& sd);
+
+ // "general" fields
+ bool getAltImageEnable() const { return mAltImageEnable; }
+ MediaControls getControls() const { return mControls; }
+ std::string getCurrentURL() const { return mCurrentURL; }
+ std::string getHomeURL() const { return mHomeURL; }
+ bool getAutoLoop() const { return mAutoLoop; }
+ bool getAutoPlay() const { return mAutoPlay; }
+ bool getAutoScale() const { return mAutoScale; }
+ bool getAutoZoom() const { return mAutoZoom; }
+ bool getFirstClickInteract() const { return mFirstClickInteract; }
+ U16 getWidthPixels() const { return mWidthPixels; }
+ U16 getHeightPixels() const { return mHeightPixels; }
+
+ // "security" fields
+ bool getWhiteListEnable() const { return mWhiteListEnable; }
+ const std::vector<std::string> &getWhiteList() const { return mWhiteList; }
+
+ // "permissions" fields
+ U8 getPermsInteract() const { return mPermsInteract; }
+ U8 getPermsControl() const { return mPermsControl; }
+
+ // Setters. Those that return a U32 return a status error code
+ // See lllslconstants.h
+
+ // "general" fields
+ U32 setAltImageEnable(bool alt_image_enable) { mAltImageEnable = alt_image_enable; return LSL_STATUS_OK; }
+ U32 setControls(MediaControls controls);
+ U32 setCurrentURL(const std::string& current_url);
+ U32 setHomeURL(const std::string& home_url);
+ U32 setAutoLoop(bool auto_loop) { mAutoLoop = auto_loop; return LSL_STATUS_OK; }
+ U32 setAutoPlay(bool auto_play) { mAutoPlay = auto_play; return LSL_STATUS_OK; }
+ U32 setAutoScale(bool auto_scale) { mAutoScale = auto_scale; return LSL_STATUS_OK; }
+ U32 setAutoZoom(bool auto_zoom) { mAutoZoom = auto_zoom; return LSL_STATUS_OK; }
+ U32 setFirstClickInteract(bool first_click) { mFirstClickInteract = first_click; return LSL_STATUS_OK; }
+ U32 setWidthPixels(U16 width);
+ U32 setHeightPixels(U16 height);
+
+ // "security" fields
+ U32 setWhiteListEnable( bool whitelist_enable ) { mWhiteListEnable = whitelist_enable; return LSL_STATUS_OK; }
+ U32 setWhiteList( const std::vector<std::string> &whitelist );
+ U32 setWhiteList( const LLSD &whitelist ); // takes an LLSD array
+
+ // "permissions" fields
+ U32 setPermsInteract( U8 val );
+ U32 setPermsControl( U8 val );
+
+ const LLUUID& getMediaID() const;
+
+ // Helper function to check a candidate URL against the whitelist
+ // Returns true iff candidate URL passes (or if there is no whitelist), false otherwise
+ bool checkCandidateUrl(const std::string& url) const;
+
+public:
+ // Static function to check a URL against a whitelist
+ // Returns true iff url passes the given whitelist
+ static bool checkUrlAgainstWhitelist(const std::string &url,
+ const std::vector<std::string> &whitelist);
+
+public:
+ // LLSD key defines
+ // "general" fields
+ static const char* ALT_IMAGE_ENABLE_KEY;
+ static const char* CONTROLS_KEY;
+ static const char* CURRENT_URL_KEY;
+ static const char* HOME_URL_KEY;
+ static const char* AUTO_LOOP_KEY;
+ static const char* AUTO_PLAY_KEY;
+ static const char* AUTO_SCALE_KEY;
+ static const char* AUTO_ZOOM_KEY;
+ static const char* FIRST_CLICK_INTERACT_KEY;
+ static const char* WIDTH_PIXELS_KEY;
+ static const char* HEIGHT_PIXELS_KEY;
+
+ // "security" fields
+ static const char* WHITELIST_ENABLE_KEY;
+ static const char* WHITELIST_KEY;
+
+ // "permissions" fields
+ static const char* PERMS_INTERACT_KEY;
+ static const char* PERMS_CONTROL_KEY;
+
+ // Field enumerations & constants
+
+ // *NOTE: DO NOT change the order of these, and do not insert values
+ // in the middle!
+ // Add values to the end, and make sure to change PARAM_MAX_ID!
+ enum Fields {
+ ALT_IMAGE_ENABLE_ID = 0,
+ CONTROLS_ID = 1,
+ CURRENT_URL_ID = 2,
+ HOME_URL_ID = 3,
+ AUTO_LOOP_ID = 4,
+ AUTO_PLAY_ID = 5,
+ AUTO_SCALE_ID = 6,
+ AUTO_ZOOM_ID = 7,
+ FIRST_CLICK_INTERACT_ID = 8,
+ WIDTH_PIXELS_ID = 9,
+ HEIGHT_PIXELS_ID = 10,
+ WHITELIST_ENABLE_ID = 11,
+ WHITELIST_ID = 12,
+ PERMS_INTERACT_ID = 13,
+ PERMS_CONTROL_ID = 14,
+ PARAM_MAX_ID = PERMS_CONTROL_ID
+ };
+
+ // "permissions" values
+ // (e.g. (PERM_OWNER | PERM_GROUP) sets permissions on for OWNER and GROUP
+ static const U8 PERM_NONE = 0x0;
+ static const U8 PERM_OWNER = 0x1;
+ static const U8 PERM_GROUP = 0x2;
+ static const U8 PERM_ANYONE = 0x4;
+ static const U8 PERM_ALL = PERM_OWNER|PERM_GROUP|PERM_ANYONE;
+ static const U8 PERM_MASK = PERM_OWNER|PERM_GROUP|PERM_ANYONE;
+
+ // Limits (in bytes)
+ static const U32 MAX_URL_LENGTH = 1024;
+ static const U32 MAX_WHITELIST_SIZE = 1024;
+ static const U32 MAX_WHITELIST_COUNT = 64;
+ static const U16 MAX_WIDTH_PIXELS = 2048;
+ static const U16 MAX_HEIGHT_PIXELS = 2048;
+
+private:
+
+ U32 setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit );
+ U32 setCurrentURLInternal( const std::string &url, bool check_whitelist);
+ bool fromLLSDInternal(const LLSD &sd, bool overwrite);
+
+private:
+ // "general" fields
+ bool mAltImageEnable;
+ MediaControls mControls;
+ std::string mCurrentURL;
+ std::string mHomeURL;
+ bool mAutoLoop;
+ bool mAutoPlay;
+ bool mAutoScale;
+ bool mAutoZoom;
+ bool mFirstClickInteract;
+ U16 mWidthPixels;
+ U16 mHeightPixels;
+
+ // "security" fields
+ bool mWhiteListEnable;
+ std::vector<std::string> mWhiteList;
+
+ // "permissions" fields
+ U8 mPermsInteract;
+ U8 mPermsControl;
+
+ mutable LLUUID *mMediaIDp; // temporary id assigned to media on the viewer
+};
+
+#endif
+
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 4e733ff56a..d307d4bbfb 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -1319,6 +1319,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f;
retval |= setTEColor(i, color);
+
}
return retval;
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 3bcd831142..b534939dfc 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -32,13 +32,31 @@
#include "linden_common.h"
+#include "lluuid.h"
+#include "llmediaentry.h"
#include "lltextureentry.h"
#include "llsdutil.h"
+#include "v4color.h"
const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess
const LLTextureEntry LLTextureEntry::null;
+// Some LLSD keys. Do not change these!
+#define OBJECT_ID_KEY_STR "object_id"
+#define TEXTURE_INDEX_KEY_STR "texture_index"
+#define OBJECT_MEDIA_VERSION_KEY_STR "object_media_version"
+#define OBJECT_MEDIA_DATA_KEY_STR "object_media_data"
+#define TEXTURE_MEDIA_DATA_KEY_STR "media_data"
+
+/*static*/ const char* LLTextureEntry::OBJECT_ID_KEY = OBJECT_ID_KEY_STR;
+/*static*/ const char* LLTextureEntry::OBJECT_MEDIA_DATA_KEY = OBJECT_MEDIA_DATA_KEY_STR;
+/*static*/ const char* LLTextureEntry::MEDIA_VERSION_KEY = OBJECT_MEDIA_VERSION_KEY_STR;
+/*static*/ const char* LLTextureEntry::TEXTURE_INDEX_KEY = TEXTURE_INDEX_KEY_STR;
+/*static*/ const char* LLTextureEntry::TEXTURE_MEDIA_DATA_KEY = TEXTURE_MEDIA_DATA_KEY_STR;
+
+static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:";
+
// static
LLTextureEntry* LLTextureEntry::newTextureEntry()
{
@@ -47,16 +65,19 @@ LLTextureEntry* LLTextureEntry::newTextureEntry()
//===============================================================
LLTextureEntry::LLTextureEntry()
+ : mMediaEntry(NULL)
{
init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
+ : mMediaEntry(NULL)
{
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
+ : mMediaEntry(NULL)
{
mID = rhs.mID;
mScaleS = rhs.mScaleS;
@@ -68,6 +89,10 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
+ if (rhs.mMediaEntry != NULL) {
+ // Make a copy
+ mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
+ }
}
LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
@@ -84,6 +109,16 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
+ if (mMediaEntry != NULL) {
+ delete mMediaEntry;
+ }
+ if (rhs.mMediaEntry != NULL) {
+ // Make a copy
+ mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
+ }
+ else {
+ mMediaEntry = NULL;
+ }
}
return *this;
@@ -103,10 +138,19 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
mGlow = 0;
setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
+ if (mMediaEntry != NULL) {
+ delete mMediaEntry;
+ }
+ mMediaEntry = NULL;
}
LLTextureEntry::~LLTextureEntry()
{
+ if(mMediaEntry)
+ {
+ delete mMediaEntry;
+ mMediaEntry = NULL;
+ }
}
bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
@@ -158,10 +202,17 @@ void LLTextureEntry::asLLSD(LLSD& sd) const
sd["bump"] = getBumpShiny();
sd["fullbright"] = getFullbright();
sd["media_flags"] = mMediaFlags;
+ if (hasMedia()) {
+ LLSD mediaData;
+ if (NULL != getMediaData()) {
+ getMediaData()->asLLSD(mediaData);
+ }
+ sd[TEXTURE_MEDIA_DATA_KEY] = mediaData;
+ }
sd["glow"] = mGlow;
}
-bool LLTextureEntry::fromLLSD(LLSD& sd)
+bool LLTextureEntry::fromLLSD(const LLSD& sd)
{
const char *w, *x;
w = "imageid";
@@ -206,6 +257,17 @@ bool LLTextureEntry::fromLLSD(LLSD& sd)
{
setMediaTexGen( sd[w].asInteger() );
} else goto fail;
+ // If the "has media" flag doesn't match the fact that
+ // media data exists, updateMediaData will "fix" it
+ // by either clearing or setting the flag
+ w = TEXTURE_MEDIA_DATA_KEY;
+ if (hasMedia() != sd.has(w))
+ {
+ llwarns << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() <<
+ ") does not match presence of media_data (" << sd.has(w) << "). Fixing." << llendl;
+ }
+ updateMediaData(sd[w]);
+
w = "glow";
if (sd.has(w))
{
@@ -370,7 +432,19 @@ S32 LLTextureEntry::setMediaTexGen(U8 media)
if (mMediaFlags != media)
{
mMediaFlags = media;
- return TEM_CHANGE_TEXTURE;
+
+ // Special code for media handling
+ if( hasMedia() && mMediaEntry == NULL)
+ {
+ mMediaEntry = new LLMediaEntry;
+ }
+ else if ( ! hasMedia() && mMediaEntry != NULL)
+ {
+ delete mMediaEntry;
+ mMediaEntry = NULL;
+ }
+
+ return TEM_CHANGE_MEDIA;
}
return TEM_CHANGE_NONE;
}
@@ -430,7 +504,19 @@ S32 LLTextureEntry::setMediaFlags(U8 media_flags)
{
mMediaFlags &= ~TEM_MEDIA_MASK;
mMediaFlags |= media_flags;
- return TEM_CHANGE_TEXTURE;
+
+ // Special code for media handling
+ if( hasMedia() && mMediaEntry == NULL)
+ {
+ mMediaEntry = new LLMediaEntry;
+ }
+ else if ( ! hasMedia() && mMediaEntry != NULL)
+ {
+ delete mMediaEntry;
+ mMediaEntry = NULL;
+ }
+
+ return TEM_CHANGE_MEDIA;
}
return TEM_CHANGE_NONE;
}
@@ -456,3 +542,107 @@ S32 LLTextureEntry::setGlow(F32 glow)
}
return TEM_CHANGE_NONE;
}
+
+void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
+{
+ mMediaFlags |= MF_HAS_MEDIA;
+ if (NULL != mMediaEntry)
+ {
+ delete mMediaEntry;
+ }
+ mMediaEntry = new LLMediaEntry(media_entry);
+}
+
+bool LLTextureEntry::updateMediaData(const LLSD& media_data)
+{
+ if (media_data.isUndefined())
+ {
+ // clear the media data
+ clearMediaData();
+ return false;
+ }
+ else {
+ mMediaFlags |= MF_HAS_MEDIA;
+ if (mMediaEntry == NULL)
+ {
+ mMediaEntry = new LLMediaEntry;
+ }
+ // *NOTE: this will *clobber* all of the fields in mMediaEntry
+ // with whatever fields are present (or not present) in media_data!
+ mMediaEntry->fromLLSD(media_data);
+ return true;
+ }
+}
+
+void LLTextureEntry::clearMediaData()
+{
+ mMediaFlags &= ~MF_HAS_MEDIA;
+ if (mMediaEntry != NULL) {
+ delete mMediaEntry;
+ }
+ mMediaEntry = NULL;
+}
+
+void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields)
+{
+ mMediaFlags |= MF_HAS_MEDIA;
+ if (mMediaEntry == NULL)
+ {
+ mMediaEntry = new LLMediaEntry;
+ }
+ // *NOTE: this will *merge* the data in media_fields
+ // with the data in our media entry
+ mMediaEntry->mergeFromLLSD(media_fields);
+}
+
+//static
+std::string LLTextureEntry::touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id)
+{
+ // XXX TODO: make media version string binary (base64-encoded?)
+ // Media "URL" is a representation of a version and the last-touched agent
+ // x-mv:nnnnn/agent-id
+ // where "nnnnn" is version number
+ // *NOTE: not the most efficient code in the world...
+ U32 current_version = getVersionFromMediaVersionString(in_version) + 1;
+ const size_t MAX_VERSION_LEN = 10; // 2^32 fits in 10 decimal digits
+ char buf[MAX_VERSION_LEN+1];
+ snprintf(buf, (int)MAX_VERSION_LEN+1, "%0*u", (int)MAX_VERSION_LEN, current_version); // added int cast to fix warning/breakage on mac.
+ return MEDIA_VERSION_STRING_PREFIX + buf + "/" + agent_id.asString();
+}
+
+//static
+U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string)
+{
+ U32 version = 0;
+ if (!version_string.empty())
+ {
+ size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
+ if (found != std::string::npos)
+ {
+ found = version_string.find_first_of("/", found);
+ std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found);
+ version = strtoul(v.c_str(),NULL,10);
+ }
+ }
+ return version;
+}
+
+//static
+LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string)
+{
+ LLUUID id;
+ if (!version_string.empty())
+ {
+ size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
+ if (found != std::string::npos)
+ {
+ found = version_string.find_first_of("/", found);
+ if (found != std::string::npos)
+ {
+ std::string v = version_string.substr(found + 1);
+ id.set(v);
+ }
+ }
+ }
+ return id;
+}
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index 84870e93e6..8d2834f78c 100644
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -37,10 +37,13 @@
#include "v4color.h"
#include "llsd.h"
+// These bits are used while unpacking TEM messages to tell which aspects of
+// the texture entry changed.
const S32 TEM_CHANGE_NONE = 0x0;
const S32 TEM_CHANGE_COLOR = 0x1;
const S32 TEM_CHANGE_TEXTURE = 0x2;
-const S32 TEM_INVALID = 0x4;
+const S32 TEM_CHANGE_MEDIA = 0x4;
+const S32 TEM_INVALID = 0x8;
const S32 TEM_BUMPMAP_COUNT = 32;
@@ -65,6 +68,8 @@ const S32 TEM_MEDIA_MASK = 0x01;
const S32 TEM_TEX_GEN_MASK = 0x06;
const S32 TEM_TEX_GEN_SHIFT = 1;
+// forward declarations
+class LLMediaEntry;
class LLTextureEntry
{
@@ -92,7 +97,7 @@ public:
LLSD asLLSD() const;
void asLLSD(LLSD& sd) const;
operator LLSD() const { return asLLSD(); }
- bool fromLLSD(LLSD& sd);
+ bool fromLLSD(const LLSD& sd);
virtual LLTextureEntry* newBlank() const;
virtual LLTextureEntry* newCopy() const;
@@ -140,9 +145,35 @@ public:
U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; }
U8 getMediaTexGen() const { return mMediaFlags; }
F32 getGlow() const { return mGlow; }
-
+
+ // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
+ // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
+ // to NOT return NULL.
+ bool hasMedia() const { return (bool)(mMediaFlags & MF_HAS_MEDIA); }
+ LLMediaEntry* getMediaData() const { return mMediaEntry; }
+
+ // Completely change the media data on this texture entry.
+ void setMediaData(const LLMediaEntry &media_entry);
+ // Returns true if media data was updated, false if it was cleared
+ bool updateMediaData(const LLSD& media_data);
+ // Clears media data, and sets the media flags bit to 0
+ void clearMediaData();
+ // Merges the given LLSD of media fields with this media entry.
+ // Only those fields that are set that match the keys in
+ // LLMediaEntry will be affected. If no fields are set or if
+ // the LLSD is undefined, this is a no-op.
+ void mergeIntoMediaData(const LLSD& media_fields);
+
+ // Takes a media version string (an empty string or a previously-returned string)
+ // and returns a "touched" string, touched by agent_id
+ static std::string touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id);
+ // Given a media version string, return the version
+ static U32 getVersionFromMediaVersionString(const std::string &version_string);
+ // Given a media version string, return the UUID of the agent
+ static LLUUID getAgentIDFromMediaVersionString(const std::string &version_string);
+
// Media flags
- enum { MF_NONE = 0x0, MF_WEB_PAGE = 0x1 };
+ enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 };
public:
F32 mScaleS; // S, T offset
@@ -152,6 +183,14 @@ public:
F32 mRotation; // anti-clockwise rotation in rad about the bottom left corner
static const LLTextureEntry null;
+
+ // LLSD key defines
+ static const char* OBJECT_ID_KEY;
+ static const char* OBJECT_MEDIA_DATA_KEY;
+ static const char* MEDIA_VERSION_KEY;
+ static const char* TEXTURE_INDEX_KEY;
+ static const char* TEXTURE_MEDIA_DATA_KEY;
+
protected:
LLUUID mID; // Texture GUID
LLColor4 mColor;
@@ -159,6 +198,9 @@ protected:
U8 mMediaFlags; // replace with web page, movie, etc.
F32 mGlow;
+ // Note the media data is not sent via the same message structure as the rest of the TE
+ LLMediaEntry* mMediaEntry; // The media data for the face
+
// NOTE: when adding new data to this class, in addition to adding it to the serializers asLLSD/fromLLSD and the
// message packers (e.g. LLPrimitive::packTEMessage) you must also implement its copy in LLPrimitive::copyTEs()
diff --git a/indra/llprimitive/tests/llmediaentry_test.cpp b/indra/llprimitive/tests/llmediaentry_test.cpp
new file mode 100644
index 0000000000..72478d0459
--- /dev/null
+++ b/indra/llprimitive/tests/llmediaentry_test.cpp
@@ -0,0 +1,484 @@
+/**
+ * @file llmediaentry_test.cpp
+ * @brief llmediaentry unit tests
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "lltut.h"
+#include "boost/lexical_cast.hpp"
+#include "llstring.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+
+#include "../llmediaentry.h"
+#include "lllslconstants.h"
+
+#define DEFAULT_MEDIA_ENTRY "<llsd>\n\
+ <map>\n\
+ <key>alt_image_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_loop</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_play</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_scale</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_zoom</key>\n\
+ <boolean>0</boolean>\n\
+ <key>controls</key>\n\
+ <integer>0</integer>\n\
+ <key>current_url</key>\n\
+ <string />\n\
+ <key>first_click_interact</key>\n\
+ <boolean>0</boolean>\n\
+ <key>height_pixels</key>\n\
+ <integer>0</integer>\n\
+ <key>home_url</key>\n\
+ <string />\n\
+ <key>perms_control</key>\n\
+ <integer>7</integer>\n\
+ <key>perms_interact</key>\n\
+ <integer>7</integer>\n\
+ <key>whitelist_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>width_pixels</key>\n\
+ <integer>0</integer>\n\
+ </map>\n\
+ </llsd>"
+
+#define EMPTY_MEDIA_ENTRY "<llsd>\n\
+ <map>\n\
+ <key>alt_image_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_loop</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_play</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_scale</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_zoom</key>\n\
+ <boolean>0</boolean>\n\
+ <key>controls</key>\n\
+ <integer>0</integer>\n\
+ <key>current_url</key>\n\
+ <string />\n\
+ <key>first_click_interact</key>\n\
+ <boolean>0</boolean>\n\
+ <key>height_pixels</key>\n\
+ <integer>0</integer>\n\
+ <key>home_url</key>\n\
+ <string />\n\
+ <key>perms_control</key>\n\
+ <integer>0</integer>\n\
+ <key>perms_interact</key>\n\
+ <integer>0</integer>\n\
+ <key>whitelist_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>width_pixels</key>\n\
+ <integer>0</integer>\n\
+ </map>\n\
+ </llsd>"
+
+#define PARTIAL_MEDIA_ENTRY(CURRENT_URL) "<llsd>\n\
+ <map>\n\
+ <key>alt_image_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_loop</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_play</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_scale</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_zoom</key>\n\
+ <boolean>0</boolean>\n\
+ <key>controls</key>\n\
+ <integer>0</integer>\n\
+ <key>current_url</key>\n\
+ <string>" CURRENT_URL "</string>\n\
+ <key>first_click_interact</key>\n\
+ <boolean>0</boolean>\n\
+ <key>height_pixels</key>\n\
+ <integer>0</integer>\n\
+ <key>home_url</key>\n\
+ <string />\n\
+ <key>perms_control</key>\n\
+ <integer>0</integer>\n\
+ <key>perms_interact</key>\n\
+ <integer>0</integer>\n\
+ <key>whitelist_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>width_pixels</key>\n\
+ <integer>0</integer>\n\
+ </map>\n\
+ </llsd>"
+
+namespace tut
+{
+ // this is fixture data that gets created before each test and destroyed
+ // after each test. this is where we put all of the setup/takedown code
+ // and data needed for each test.
+ struct MediaEntry_test
+ {
+ MediaEntry_test() {
+ emptyMediaEntryStr = EMPTY_MEDIA_ENTRY;
+ std::istringstream e(EMPTY_MEDIA_ENTRY);
+ LLSDSerialize::fromXML(emptyMediaEntryLLSD, e);
+ defaultMediaEntryStr = DEFAULT_MEDIA_ENTRY;
+ std::istringstream d(DEFAULT_MEDIA_ENTRY);
+ LLSDSerialize::fromXML(defaultMediaEntryLLSD, d);
+ }
+ std::string emptyMediaEntryStr;
+ LLSD emptyMediaEntryLLSD;
+ std::string defaultMediaEntryStr;
+ LLSD defaultMediaEntryLLSD;
+ };
+
+ typedef test_group<MediaEntry_test, 55> factory;
+ typedef factory::object object;
+}
+
+
+namespace
+{
+ // this is for naming our tests to make pretty output
+ tut::factory tf("MediaEntry Test");
+}
+
+namespace tut
+{
+ bool llsd_equals(const LLSD& a, const LLSD& b) {
+ // cheesy, brute force, but it works
+ return std::string(ll_pretty_print_sd(a)) == std::string(ll_pretty_print_sd(b));
+ }
+
+ void ensure_llsd_equals(const std::string& msg, const LLSD& expected, const LLSD& actual)
+ {
+ if (! llsd_equals(expected, actual))
+ {
+ std::string message = msg;
+ message += ": actual: ";
+ message += ll_pretty_print_sd(actual);
+ message += "\n expected: ";
+ message += ll_pretty_print_sd(expected);
+ message += "\n";
+ ensure(message, false);
+ }
+ }
+
+ void ensure_string_equals(const std::string& msg, const std::string& expected, const std::string& actual)
+ {
+ if ( expected != actual )
+ {
+ std::string message = msg;
+ message += ": actual: ";
+ message += actual;
+ message += "\n expected: ";
+ message += expected;
+ message += "\n";
+ ensure(message, false);
+ }
+ }
+
+ void set_whitelist(LLMediaEntry &entry, const char *str)
+ {
+ std::vector<std::string> tokens;
+ LLStringUtil::getTokens(std::string(str), tokens, ",");
+ entry.setWhiteList(tokens);
+ }
+
+ void whitelist_test(bool enable, const char *whitelist, const char *candidate_url, bool expected_pass)
+ {
+ std::string message = "Whitelist test";
+ LLMediaEntry entry;
+ entry.setWhiteListEnable(enable);
+ set_whitelist(entry, whitelist);
+ bool passed_whitelist = entry.checkCandidateUrl(candidate_url);
+ if (passed_whitelist != expected_pass)
+ {
+ message += " failed: expected ";
+ message += (expected_pass) ? "" : "NOT ";
+ message += "to match\nwhitelist = ";
+ message += whitelist;
+ message += "\ncandidate_url = ";
+ message += candidate_url;
+ }
+ ensure(message, expected_pass == passed_whitelist);
+ }
+
+ void whitelist_test(const char *whitelist, const char *candidate_url, bool expected_pass)
+ {
+ whitelist_test(true, whitelist, candidate_url, expected_pass);
+ }
+ void whitelist_test(const char *whitelist, const char *candidate_url)
+ {
+ whitelist_test(true, whitelist, candidate_url, true);
+ }
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("Test LLMediaEntry Instantiation");
+ LLMediaEntry entry;
+ ensure_llsd_equals(get_test_name(), defaultMediaEntryLLSD, entry.asLLSD());
+
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ set_test_name("Test LLMediaEntry Instantiation from LLSD");
+ LLMediaEntry entry;
+ LLSD sd;
+ entry.fromLLSD(sd);
+ ensure_llsd_equals(get_test_name() + " failed", emptyMediaEntryLLSD, entry.asLLSD());
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ set_test_name("Test LLMediaEntry Partial Instantiation from LLSD");
+ LLMediaEntry entry;
+ LLSD sd;
+ sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.example.com";
+ entry.fromLLSD(sd);
+ LLSD golden;
+ std::istringstream p(PARTIAL_MEDIA_ENTRY("http://www.example.com"));
+ LLSDSerialize::fromXML(golden,p);
+ ensure_llsd_equals(get_test_name() + " failed", golden, entry.asLLSD());
+ }
+
+ // limit tests
+ const char *URL_OK = "http://www.example.com";
+ const char *URL_TOO_BIG = "http://www.example.com.qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";
+
+ template<> template<>
+ void object::test<4>()
+ {
+ set_test_name("Test Limits on setting current URL");
+ LLMediaEntry entry;
+ U32 status = entry.setCurrentURL(URL_OK);
+ ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK);
+ status = entry.setCurrentURL(URL_TOO_BIG);
+ ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR);
+ }
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("Test Limits on setting home URL");
+ LLMediaEntry entry;
+ U32 status = entry.setHomeURL(URL_OK);
+ ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK);
+ status = entry.setHomeURL(URL_TOO_BIG);
+ ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR);
+ }
+
+ template<> template<>
+ void object::test<6>()
+ {
+ set_test_name("Test Limits on setting whitelist");
+
+ // Test a valid list
+ LLMediaEntry entry;
+ std::vector<std::string> whitelist;
+ whitelist.push_back(std::string(URL_OK));
+ S32 status = entry.setWhiteList(whitelist);
+ ensure(get_test_name() + " invalid result", status == LSL_STATUS_OK);
+ ensure(get_test_name() + " failed", whitelist == entry.getWhiteList());
+ }
+
+ template<> template<>
+ void object::test<7>()
+ {
+ set_test_name("Test Limits on setting whitelist too big");
+
+ // Test an invalid list
+ LLMediaEntry entry;
+ std::vector<std::string> whitelist, empty;
+ whitelist.push_back(std::string(URL_OK));
+ whitelist.push_back(std::string(URL_TOO_BIG));
+ S32 status = entry.setWhiteList(whitelist);
+ ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR);
+ ensure(get_test_name() + " failed", empty == entry.getWhiteList());
+ }
+
+ template<> template<>
+ void object::test<8>()
+ {
+ set_test_name("Test Limits on setting whitelist too many");
+
+ // Test an invalid list
+ LLMediaEntry entry;
+ std::vector<std::string> whitelist, empty;
+ for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) {
+ whitelist.push_back("Q");
+ }
+ S32 status = entry.setWhiteList(whitelist);
+ ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR);
+ ensure(get_test_name() + " failed", empty == entry.getWhiteList());
+ }
+
+ template<> template<>
+ void object::test<9>()
+ {
+ set_test_name("Test to make sure both setWhiteList() functions behave the same");
+
+ // Test a valid list
+ std::vector<std::string> whitelist, empty;
+ LLSD whitelist_llsd;
+ whitelist.push_back(std::string(URL_OK));
+ whitelist_llsd.append(std::string(URL_OK));
+ LLMediaEntry entry1, entry2;
+ ensure(get_test_name() + " setWhiteList(s) don't match",
+ entry1.setWhiteList(whitelist) == LSL_STATUS_OK &&
+ entry2.setWhiteList(whitelist_llsd)== LSL_STATUS_OK );
+ ensure(get_test_name() + " failed",
+ entry1.getWhiteList() == entry2.getWhiteList());
+ }
+
+ template<> template<>
+ void object::test<10>()
+ {
+ set_test_name("Test to make sure both setWhiteList() functions behave the same");
+
+ // Test an invalid list
+ std::vector<std::string> whitelist, empty;
+ LLSD whitelist_llsd;
+ whitelist.push_back(std::string(URL_OK));
+ whitelist.push_back(std::string(URL_TOO_BIG));
+ whitelist_llsd.append(std::string(URL_OK));
+ whitelist_llsd.append(std::string(URL_TOO_BIG));
+ LLMediaEntry entry1, entry2;
+ ensure(get_test_name() + " setWhiteList(s) don't match",
+ entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR &&
+ entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR);
+ ensure(get_test_name() + " failed",
+ empty == entry1.getWhiteList() &&
+ empty == entry2.getWhiteList());
+ }
+
+ template<> template<>
+ void object::test<11>()
+ {
+ set_test_name("Test to make sure both setWhiteList() functions behave the same");
+
+ // Test an invalid list, too many
+ std::vector<std::string> whitelist, empty;
+ LLSD whitelist_llsd;
+ for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) {
+ whitelist.push_back("Q");
+ whitelist_llsd.append("Q");
+ }
+ LLMediaEntry entry1, entry2;
+ ensure(get_test_name() + " invalid result",
+ entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR &&
+ entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR);
+ ensure(get_test_name() + " failed",
+ empty == entry1.getWhiteList() &&
+ empty == entry2.getWhiteList());
+ }
+
+ // Whitelist check tests
+
+ // Check the "empty whitelist" case
+ template<> template<>
+ void object::test<12>() { whitelist_test("", "http://www.example.com", true); }
+
+ // Check the "missing scheme" case
+ template<> template<>
+ void object::test<13>() { whitelist_test("www.example.com", "http://www.example.com", true); }
+
+ // Check the "exactly the same" case
+ template<> template<>
+ void object::test<14>() { whitelist_test("http://example.com", "http://example.com", true); }
+
+ // Check the enable flag
+ template<> template<>
+ void object::test<15>() { whitelist_test(false, "www.example.com", "http://www.secondlife.com", true); }
+ template<> template<>
+ void object::test<16>() { whitelist_test(true, "www.example.com", "http://www.secondlife.com", false); }
+
+ // Check permutations of trailing slash:
+ template<> template<>
+ void object::test<17>() { whitelist_test("http://www.example.com", "http://www.example.com/", true); }
+ template<> template<>
+ void object::test<18>() { whitelist_test("http://www.example.com/", "http://www.example.com/", true); }
+ template<> template<>
+ void object::test<19>() { whitelist_test("http://www.example.com/", "http://www.example.com", false); }
+ template<> template<>
+ void object::test<20>() { whitelist_test("http://www.example.com", "http://www.example.com/foobar", true); }
+ template<> template<>
+ void object::test<21>() { whitelist_test("http://www.example.com/", "http://www.example.com/foobar", false); }
+
+
+ // More cases...
+ template<> template<>
+ void object::test<22>() { whitelist_test("http://example.com", "http://example.com/wiki", true); }
+ template<> template<>
+ void object::test<23>() { whitelist_test("www.example.com", "http://www.example.com/help", true); }
+ template<> template<>
+ void object::test<24>() { whitelist_test("http://www.example.com", "http://wwwexample.com", false); }
+ template<> template<>
+ void object::test<25>() { whitelist_test("http://www.example.com", "http://www.example.com/wiki", true); }
+ template<> template<>
+ void object::test<26>() { whitelist_test("example.com", "http://wwwexample.com", false); }
+ template<> template<>
+ void object::test<27>() { whitelist_test("http://www.example.com/", "http://www.amazon.com/wiki", false); }
+ template<> template<>
+ void object::test<28>() { whitelist_test("www.example.com", "http://www.amazon.com", false); }
+
+ // regexp cases
+ template<> template<>
+ void object::test<29>() { whitelist_test("*.example.com", "http://www.example.com", true); }
+ template<> template<>
+ void object::test<30>() { whitelist_test("*.example.com", "http://www.amazon.com", false); }
+ template<> template<>
+ void object::test<31>() { whitelist_test("*.example.com", "http://www.example.com/foo/bar", true); }
+ template<> template<>
+ void object::test<32>() { whitelist_test("*.example.com", "http:/example.com/foo/bar", false); }
+ template<> template<>
+ void object::test<33>() { whitelist_test("*example.com", "http://example.com/foo/bar", true); }
+ template<> template<>
+ void object::test<34>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?example.com", false); }
+ template<> template<>
+ void object::test<35>() { whitelist_test("example.com", "http://my.virus.com/foo/bar?example.com", false); }
+ template<> template<>
+ void object::test<36>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?*example.com", false); }
+ template<> template<>
+ void object::test<37>() { whitelist_test("http://*example.com", "http://www.example.com", true); }
+ template<> template<>
+ void object::test<38>() { whitelist_test("http://*.example.com", "http://www.example.com", true); }
+ template<> template<>
+ void object::test<39>() { whitelist_test("http://*.e$?^.com", "http://www.e$?^.com", true); }
+ template<> template<>
+ void object::test<40>() { whitelist_test("*.example.com/foo/bar", "http://www.example.com/", false); }
+ template<> template<>
+ void object::test<41>() { whitelist_test("*.example.com/foo/bar", "http://example.com/foo/bar", false); }
+ template<> template<>
+ void object::test<42>() { whitelist_test("http://*.example.com/foo/bar", "http://www.example.com", false); }
+ template<> template<>
+ void object::test<43>() { whitelist_test("http://*.example.com", "https://www.example.com", false); }
+ template<> template<>
+ void object::test<44>() { whitelist_test("http*://*.example.com", "rtsp://www.example.com", false); }
+ template<> template<>
+ void object::test<45>() { whitelist_test("http*://*.example.com", "https://www.example.com", true); }
+ template<> template<>
+ void object::test<46>() { whitelist_test("example.com", "http://www.example.com", false); }
+ template<> template<>
+ void object::test<47>() { whitelist_test("www.example.com", "http://www.example.com:80", false); }
+ template<> template<>
+ void object::test<48>() { whitelist_test("www.example.com", "http://www.example.com", true); }
+ template<> template<>
+ void object::test<49>() { whitelist_test("www.example.com/", "http://www.example.com", false); }
+ template<> template<>
+ void object::test<50>() { whitelist_test("www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true); }
+ // Path only
+ template<> template<>
+ void object::test<51>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/baz", true); }
+ template<> template<>
+ void object::test<52>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/", false); }
+}
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 1e6b216a61..0a284f0088 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -85,6 +85,7 @@ set(llui_SOURCE_FILES
lltextbox.cpp
lltexteditor.cpp
lltextparser.cpp
+ lltransientfloatermgr.cpp
lltransutil.cpp
lltooltip.cpp
llui.cpp
@@ -129,7 +130,7 @@ set(llui_HEADER_FILES
llfocusmgr.h
llfunctorregistry.h
llhandle.h
- llhtmlhelp.h
+ llhelp.h
lliconctrl.h
llkeywords.h
lllayoutstack.h
@@ -171,6 +172,7 @@ set(llui_HEADER_FILES
lltexteditor.h
lltextparser.h
lltooltip.h
+ lltransientfloatermgr.h
lltransutil.h
lluicolortable.h
lluiconstants.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index fa13ced037..b9613b502c 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -39,7 +39,6 @@
#include "llstring.h"
// Project includes
-#include "llhtmlhelp.h"
#include "llkeyboard.h"
#include "llui.h"
#include "lluiconstants.h"
@@ -49,8 +48,10 @@
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llwindow.h"
+#include "llnotifications.h"
#include "llrender.h"
#include "lluictrlfactory.h"
+#include "llhelp.h"
static LLDefaultChildRegistry::Register<LLButton> r("button");
@@ -92,7 +93,6 @@ LLButton::Params::Params()
mouse_held_callback("mouse_held_callback"),
is_toggle("is_toggle", false),
scale_image("scale_image", true),
- help_url("help_url"),
hover_glow_amount("hover_glow_amount"),
commit_on_return("commit_on_return", true),
picture_style("picture_style", false)
@@ -173,11 +173,6 @@ LLButton::LLButton(const LLButton::Params& p)
mMouseDownTimer.stop();
- if (p.help_url.isProvided())
- {
- setHelpURLCallback(p.help_url);
- }
-
// if custom unselected button image provided...
if (p.image_unselected != default_params.image_unselected)
{
@@ -1034,24 +1029,6 @@ void LLButton::addImageAttributeToXML(LLXMLNodePtr node,
}
}
-void clicked_help(void* data)
-{
- LLButton* self = (LLButton*)data;
- if (!self) return;
-
- if (!LLUI::sHtmlHelp)
- {
- return;
- }
-
- LLUI::sHtmlHelp->show(self->getHelpURL());
-}
-
-void LLButton::setHelpURLCallback(const std::string &help_url)
-{
- mHelpURL = help_url;
- setClickedCallback(clicked_help,this);
-}
// static
void LLButton::toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname)
@@ -1077,6 +1054,24 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname));
}
+// static
+void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname)
+{
+ // search back through the button's parents for a panel
+ // with a help_topic string defined
+ std::string help_topic;
+ if (LLUI::sHelpImpl &&
+ ctrl->findHelpTopic(help_topic))
+ {
+ LLUI::sHelpImpl->showTopic(help_topic);
+ return; // success
+ }
+
+ // display an error if we can't find a help_topic string.
+ // fix this by adding a help_topic attribute to the xui file
+ LLNotifications::instance().add("UnableToFindHelpTopic");
+}
+
void LLButton::resetMouseDownTimer()
{
mMouseDownTimer.stop();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 06e1dac914..04716d605b 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -118,7 +118,6 @@ public:
commit_on_return,
picture_style; //if true, don't display label
- Optional<std::string> help_url;
Optional<F32> hover_glow_amount;
Optional<TimeIntervalParam> held_down_delay;
@@ -230,12 +229,10 @@ public:
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
BOOL getCommitOnReturn() const { return mCommitOnReturn; }
- void setHelpURLCallback(const std::string &help_url);
- const std::string& getHelpURL() const { return mHelpURL; }
-
static void onHeldDown(void *userdata); // to be called by gIdleCallbacks
static void toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname);
static void setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname);
+ static void showHelp(LLUICtrl* ctrl, const LLSD& sdname);
protected:
const LLPointer<LLUIImage>& getImageUnselected() const { return mImageUnselected; }
@@ -314,8 +311,6 @@ private:
BOOL mCommitOnReturn;
BOOL mFadeWhenDisabled;
- std::string mHelpURL;
-
LLFrameTimer mFlashingTimer;
};
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 58aeb61728..0170ac0c6a 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -483,7 +483,6 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p)
params.max_length_bytes(mMaxChars);
params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2));
params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1));
- params.focus_lost_callback(NULL);
params.handle_edit_keys_directly(true);
params.commit_on_focus_lost(false);
params.follows.flags(FOLLOWS_ALL);
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index 93d62fd7c2..4525f0a45b 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -71,9 +71,9 @@ void LLDockableFloater::resetInstance()
if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked())
{
sInstanceHandle.get()->setVisible(FALSE);
- }
+ }
sInstanceHandle = getHandle();
- }
+ }
}
void LLDockableFloater::setVisible(BOOL visible)
@@ -105,11 +105,11 @@ void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
mDockControl.get()->off();
}
- if (!docked && pop_on_undock)
- {
- // visually pop up a little bit to emphasize the undocking
- translate(0, UNDOCK_LEAP_HEIGHT);
- }
+ if (!docked && pop_on_undock)
+ {
+ // visually pop up a little bit to emphasize the undocking
+ translate(0, UNDOCK_LEAP_HEIGHT);
+ }
}
else
{
@@ -126,8 +126,8 @@ void LLDockableFloater::draw()
mDockControl.get()->repositionDockable();
if (isDocked())
{
- mDockControl.get()->drawToungue();
- }
+ mDockControl.get()->drawToungue();
+ }
}
LLFloater::draw();
}
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index 0b16b2554c..146c7a969a 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -35,7 +35,7 @@
#include "lldockcontrol.h"
LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
- const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback) :
+ const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue)
{
mDockAt = dockAt;
@@ -49,13 +49,13 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
off();
}
- if (!(get_rect_callback))
+ if (!(get_allowed_rect_callback))
{
- mGetRectCallback = boost::bind(&LLDockControl::getEnabledRect, this, _1);
+ mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
}
else
{
- mGetRectCallback = get_rect_callback;
+ mGetAllowedRectCallback = get_allowed_rect_callback;
}
if (dockWidget != NULL)
@@ -77,7 +77,7 @@ void LLDockControl::setDock(LLView* dockWidget)
}
}
-void LLDockControl::getEnabledRect(LLRect& rect)
+void LLDockControl::getAllowedRect(LLRect& rect)
{
rect = mDockableFloater->getRootView()->getRect();
}
@@ -86,7 +86,7 @@ void LLDockControl::repositionDockable()
{
LLRect dockRect = mDockWidget->calcScreenRect();
LLRect rootRect;
- mGetRectCallback(rootRect);
+ mGetAllowedRectCallback(rootRect);
static BOOL prev_visibility = !mDockWidget->getVisible();
// recalculate dockable position if dock position changed, dock visibility changed,
@@ -100,7 +100,7 @@ void LLDockControl::repositionDockable()
mDockableFloater->setDocked(false);
// force off() since dockable may not have dockControll at this time
off();
- }
+ }
else
{
moveDockable();
@@ -123,10 +123,10 @@ bool LLDockControl::isDockVisible()
res = mDockWidget->isInVisibleChain();
if (res)
{
- LLRect dockRect = mDockWidget->calcScreenRect();
+ LLRect dockRect = mDockWidget->calcScreenRect();
switch (mDockAt)
- {
+ {
case TOP:
// check is dock inside parent rect
LLRect dockParentRect =
@@ -149,25 +149,25 @@ void LLDockControl::moveDockable()
// calculate new dockable position
LLRect dockRect = mDockWidget->calcScreenRect();
LLRect rootRect;
- mGetRectCallback(rootRect);
+ mGetAllowedRectCallback(rootRect);
- LLRect dockableRect = mDockableFloater->calcScreenRect();
- S32 x = 0;
- S32 y = 0;
- switch (mDockAt)
- {
- case TOP:
- x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+ LLRect dockableRect = mDockableFloater->calcScreenRect();
+ S32 x = 0;
+ S32 y = 0;
+ switch (mDockAt)
+ {
+ case TOP:
+ x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
// check is dockable inside root view rect
- if (x < rootRect.mLeft)
- {
- x = rootRect.mLeft;
- }
- if (x + dockableRect.getWidth() > rootRect.mRight)
- {
- x = rootRect.mRight - dockableRect.getWidth();
- }
+ if (x < rootRect.mLeft)
+ {
+ x = rootRect.mLeft;
+ }
+ if (x + dockableRect.getWidth() > rootRect.mRight)
+ {
+ x = rootRect.mRight - dockableRect.getWidth();
+ }
// calculate dock tongue position
@@ -185,21 +185,21 @@ void LLDockControl::moveDockable()
{
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
}
- mDockTongueY = dockRect.mTop;
+ mDockTongueY = dockRect.mTop;
- break;
- }
+ break;
+ }
// move dockable
- dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
- dockableRect.getHeight());
- LLRect localDocableParentRect;
- mDockableFloater->getParent()->screenRectToLocal(dockableRect,
- &localDocableParentRect);
- mDockableFloater->setRect(localDocableParentRect);
+ dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+ dockableRect.getHeight());
+ LLRect localDocableParentRect;
+ mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+ &localDocableParentRect);
+ mDockableFloater->setRect(localDocableParentRect);
- mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
- &mDockTongueX, &mDockTongueY);
+ mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+ &mDockTongueX, &mDockTongueY);
}
@@ -207,9 +207,9 @@ void LLDockControl::on()
{
if (isDockVisible())
{
- mDockableFloater->setCanDrag(false);
- mEnabled = true;
- mRecalculateDocablePosition = true;
+ mDockableFloater->setCanDrag(false);
+ mEnabled = true;
+ mRecalculateDocablePosition = true;
}
}
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index 219ddfd092..e8ffcac0ac 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -52,11 +52,11 @@ public:
public:
// callback for a function getting a rect valid for control's position
- typedef boost::function<void (LLRect& )> get_rect_callback_t;
+ typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t;
LOG_CLASS(LLDockControl);
LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
- const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback = NULL);
+ const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL);
virtual ~LLDockControl();
public:
@@ -67,13 +67,13 @@ public:
void drawToungue();
bool isDockVisible();
- // gets a rect that bounds possible positions for a dockable control
- void getEnabledRect(LLRect& rect);
+ // gets a rect that bounds possible positions for a dockable control (EXT-1111)
+ void getAllowedRect(LLRect& rect);
private:
virtual void moveDockable();
private:
- get_rect_callback_t mGetRectCallback;
+ get_allowed_rect_callback_t mGetAllowedRectCallback;
bool mEnabled;
bool mRecalculateDocablePosition;
DocAt mDockAt;
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 9fcd386c19..e9df361472 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -39,8 +39,8 @@
static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("flat_list_view");
-const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
-const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
+const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
+const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
static const std::string COMMENT_TEXTBOX = "comment_text";
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 81915731c3..ff0288a32f 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -59,6 +59,7 @@
#include "lltabcontainer.h"
#include "v2math.h"
#include "lltrans.h"
+#include "llhelp.h"
#include "llmultifloater.h"
// use this to control "jumping" behavior when Ctrl-Tabbing
@@ -66,48 +67,35 @@ const S32 TABBED_FLOATER_OFFSET = 0;
std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] =
{
- "Icon_Close_Foreground", //BUTTON_CLOSE
- "restore.tga", //BUTTON_RESTORE
- "minimize.tga", //BUTTON_MINIMIZE
- "tearoffbox.tga", //BUTTON_TEAR_OFF
- "closebox.tga", //BUTTON_EDIT
- "Icon_Dock_Foreground",
- "Icon_Undock_Foreground"
-};
-
-// Empty string means programmatic glow effect, achieved by
-// not setting explicit image.
-std::string LLFloater::sButtonHoveredImageNames[BUTTON_COUNT] =
-{
- "", //BUTTON_CLOSE
- "restore_pressed.tga", //BUTTON_RESTORE
- "minimize_pressed.tga", //BUTTON_MINIMIZE
- "tearoff_pressed.tga", //BUTTON_TEAR_OFF
- "close_in_blue.tga", //BUTTON_EDIT
- "", //BUTTON_DOCK
- "", //BUTTON_UNDOCK
+ "Icon_Close_Foreground", //BUTTON_CLOSE
+ "Icon_Restore_Foreground", //BUTTON_RESTORE
+ "Icon_Minimize_Foreground", //BUTTON_MINIMIZE
+ "tearoffbox.tga", //BUTTON_TEAR_OFF
+ "Icon_Dock_Foreground", //BUTTON_DOCK
+ "Icon_Undock_Foreground", //BUTTON_UNDOCK
+ "Icon_Help_Foreground" //BUTTON_HELP
};
std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] =
{
- "Icon_Close_Press", //BUTTON_CLOSE
- "restore_pressed.tga", //BUTTON_RESTORE
- "minimize_pressed.tga", //BUTTON_MINIMIZE
- "tearoff_pressed.tga", //BUTTON_TEAR_OFF
- "close_in_blue.tga", //BUTTON_EDIT
- "Icon_Dock_Press",
- "Icon_Undock_Press"
+ "Icon_Close_Press", //BUTTON_CLOSE
+ "Icon_Restore_Press", //BUTTON_RESTORE
+ "Icon_Minimize_Press", //BUTTON_MINIMIZE
+ "tearoff_pressed.tga", //BUTTON_TEAR_OFF
+ "Icon_Dock_Press", //BUTTON_DOCK
+ "Icon_Undock_Press", //BUTTON_UNDOCK
+ "Icon_Help_Press" //BUTTON_HELP
};
std::string LLFloater::sButtonNames[BUTTON_COUNT] =
{
- "llfloater_close_btn", //BUTTON_CLOSE
+ "llfloater_close_btn", //BUTTON_CLOSE
"llfloater_restore_btn", //BUTTON_RESTORE
"llfloater_minimize_btn", //BUTTON_MINIMIZE
"llfloater_tear_off_btn", //BUTTON_TEAR_OFF
- "llfloater_edit_btn", //BUTTON_EDIT
- "llfloater_dock_btn",
- "llfloater_undock_btn"
+ "llfloater_dock_btn", //BUTTON_DOCK
+ "llfloater_undock_btn", //BUTTON_UNDOCK
+ "llfloater_help_btn" //BUTTON_HELP
};
std::string LLFloater::sButtonToolTips[BUTTON_COUNT];
@@ -122,9 +110,9 @@ std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]=
"BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE
"BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE
"BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF
- "BUTTON_EDIT", //"Edit", //BUTTON_EDIT
"BUTTON_DOCK",
- "BUTTON_UNDOCK"
+ "BUTTON_UNDOCK",
+ "BUTTON_HELP"
};
LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
@@ -133,13 +121,12 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
LLFloater::onClickMinimize, //BUTTON_RESTORE
LLFloater::onClickMinimize, //BUTTON_MINIMIZE
LLFloater::onClickTearOff, //BUTTON_TEAR_OFF
- LLFloater::onClickEdit, //BUTTON_EDIT
- LLFloater::onClickDock,
- LLFloater::onClickDock
+ LLFloater::onClickDock, //BUTTON_DOCK
+ LLFloater::onClickDock, //BUTTON_UNDOCK
+ LLFloater::onClickHelp //BUTTON_HELP
};
LLMultiFloater* LLFloater::sHostp = NULL;
-BOOL LLFloater::sEditModeEnabled = FALSE;
BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting
LLFloater::handle_map_t LLFloater::sFloaterMap;
@@ -259,7 +246,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mMinimized(FALSE),
mForeground(FALSE),
mFirstLook(TRUE),
- mEditing(FALSE),
mButtonScale(1.0f),
mAutoFocus(TRUE), // automatically take focus when opened
mCanDock(false),
@@ -314,6 +300,12 @@ void LLFloater::initFloater()
mButtonsEnabled[BUTTON_CLOSE] = TRUE;
}
+ // Help button: '?'
+ if ( !mHelpTopic.empty() )
+ {
+ mButtonsEnabled[BUTTON_HELP] = TRUE;
+ }
+
// Minimize button only for top draggers
if ( !mDragOnLeft && mCanMinimize )
{
@@ -804,7 +796,7 @@ void LLFloater::setTitle( const std::string& title )
applyTitle();
}
-std::string LLFloater::getTitle()
+std::string LLFloater::getTitle() const
{
if (mTitle.empty())
{
@@ -822,7 +814,7 @@ void LLFloater::setShortTitle( const std::string& short_title )
applyTitle();
}
-std::string LLFloater::getShortTitle()
+std::string LLFloater::getShortTitle() const
{
if (mShortTitle.empty())
{
@@ -834,8 +826,6 @@ std::string LLFloater::getShortTitle()
}
}
-
-
BOOL LLFloater::canSnapTo(const LLView* other_view)
{
if (NULL == other_view)
@@ -1051,6 +1041,10 @@ void LLFloater::setMinimized(BOOL minimize)
reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
}
+ // don't show the help button while minimized - it's
+ // not very useful when minimized and uses up space
+ mButtonsEnabled[BUTTON_HELP] = !minimize;
+
applyTitle ();
make_ui_sound("UISndWindowClose");
@@ -1387,28 +1381,6 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)
}
}
-//static
-void LLFloater::setEditModeEnabled(BOOL enable)
-{
- if (enable != sEditModeEnabled)
- {
- S32 count = 0;
- for(handle_map_iter_t iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter)
- {
- LLFloater* floater = iter->second;
- if (!floater->isDead())
- {
- iter->second->mButtonsEnabled[BUTTON_EDIT] = enable;
- iter->second->updateButtons();
- }
- count++;
- }
- }
-
- sEditModeEnabled = enable;
-}
-
-
// static
void LLFloater::onClickMinimize(LLFloater* self)
{
@@ -1456,19 +1428,20 @@ void LLFloater::onClickTearOff(LLFloater* self)
}
// static
-void LLFloater::onClickEdit(LLFloater* self)
+void LLFloater::onClickDock(LLFloater* self)
{
- if (!self)
- return;
- self->mEditing = self->mEditing ? FALSE : TRUE;
+ if(self && self->mCanDock)
+ {
+ self->setDocked(!self->mDocked, true);
+ }
}
// static
-void LLFloater::onClickDock(LLFloater* self)
+void LLFloater::onClickHelp( LLFloater* self )
{
- if(self && self->mCanDock)
+ if (self && LLUI::sHelpImpl)
{
- self->setDocked(!self->mDocked, true);
+ LLUI::sHelpImpl->showTopic(self->getHelpTopic());
}
}
@@ -1807,17 +1780,9 @@ void LLFloater::buildButtons()
// Selected, no matter if hovered or not, is "pressed"
p.image_selected.name(sButtonPressedImageNames[i]);
p.image_hover_selected.name(sButtonPressedImageNames[i]);
- // Empty string means programmatic glow effect, achieved by
- // not setting explicit image.
- if (sButtonHoveredImageNames[i].empty())
- {
- // These icons are really small, need glow amount increased
- p.hover_glow_amount( 0.22f );
- }
- else
- {
- p.image_hover_unselected.name(sButtonHoveredImageNames[i]);
- }
+ // Use a glow effect when the user hovers over the button
+ // These icons are really small, need glow amount increased
+ p.hover_glow_amount( 0.33f );
p.click_callback.function(boost::bind(sButtonCallbacks[i], this));
p.tab_stop(false);
p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT);
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 513f6a6918..2a31ba4e8f 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -101,9 +101,9 @@ public:
BUTTON_RESTORE,
BUTTON_MINIMIZE,
BUTTON_TEAR_OFF,
- BUTTON_EDIT,
BUTTON_DOCK,
BUTTON_UNDOCK,
+ BUTTON_HELP,
BUTTON_COUNT
};
@@ -173,9 +173,9 @@ public:
void applyTitle();
const std::string& getCurrentTitle() const;
void setTitle( const std::string& title);
- std::string getTitle();
+ std::string getTitle() const;
void setShortTitle( const std::string& short_title );
- std::string getShortTitle();
+ std::string getShortTitle() const;
void setTitleVisible(bool visible);
virtual void setMinimized(BOOL b);
void moveResizeHandlesToFront();
@@ -256,12 +256,10 @@ public:
static void onClickClose(LLFloater* floater);
static void onClickMinimize(LLFloater* floater);
static void onClickTearOff(LLFloater* floater);
- static void onClickEdit(LLFloater* floater);
static void onClickDock(LLFloater* floater);
+ static void onClickHelp(LLFloater* floater);
static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }
- static void setEditModeEnabled(BOOL enable);
- static BOOL getEditModeEnabled() { return sEditModeEnabled; }
static LLMultiFloater* getFloaterHost() {return sHostp; }
protected:
@@ -331,7 +329,6 @@ private:
BOOL mFirstLook; // TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible.
- BOOL mEditing;
typedef std::set<LLHandle<LLFloater> > handle_set_t;
typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
@@ -350,11 +347,8 @@ private:
bool mDocked;
static LLMultiFloater* sHostp;
- static BOOL sEditModeEnabled;
static BOOL sQuitting;
static std::string sButtonActiveImageNames[BUTTON_COUNT];
- // Images to use when cursor hovered over an enabled button
- static std::string sButtonHoveredImageNames[BUTTON_COUNT];
static std::string sButtonPressedImageNames[BUTTON_COUNT];
static std::string sButtonNames[BUTTON_COUNT];
static std::string sButtonToolTips[BUTTON_COUNT];
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index ab9b59e252..279cbaa923 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -41,11 +41,6 @@ const F32 FOCUS_FADE_TIME = 0.3f;
// NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp.
LLFocusableElement::LLFocusableElement()
-: mFocusLostCallback(NULL),
- mFocusReceivedCallback(NULL),
- mFocusChangedCallback(NULL),
- mTopLostCallback(NULL),
- mFocusCallbackUserData(NULL)
{
}
@@ -68,35 +63,19 @@ LLFocusableElement::~LLFocusableElement()
void LLFocusableElement::onFocusReceived()
{
- if( mFocusReceivedCallback )
- {
- mFocusReceivedCallback( this, mFocusCallbackUserData );
- }
- if( mFocusChangedCallback )
- {
- mFocusChangedCallback( this, mFocusCallbackUserData );
- }
+ mFocusReceivedCallback(this);
+ mFocusChangedCallback(this);
}
void LLFocusableElement::onFocusLost()
{
- if( mFocusLostCallback )
- {
- mFocusLostCallback( this, mFocusCallbackUserData );
- }
-
- if( mFocusChangedCallback )
- {
- mFocusChangedCallback( this, mFocusCallbackUserData );
- }
+ mFocusLostCallback(this);
+ mFocusChangedCallback(this);
}
void LLFocusableElement::onTopLost()
{
- if (mTopLostCallback)
- {
- mTopLostCallback(this, mFocusCallbackUserData);
- }
+ mTopLostCallback(this);
}
BOOL LLFocusableElement::hasFocus() const
@@ -188,12 +167,9 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
view_handle_list_t new_focus_list;
// walk up the tree to root and add all views to the new_focus_list
- for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl && ctrl != LLUI::getRootView(); ctrl = ctrl->getParent())
+ for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl; ctrl = ctrl->getParent())
{
- if (ctrl)
- {
- new_focus_list.push_back(ctrl->getHandle());
- }
+ new_focus_list.push_back(ctrl->getHandle());
}
// remove all common ancestors since their focus is unchanged
@@ -216,10 +192,6 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
{
mCachedKeyboardFocusList.pop_front();
old_focus_view->onFocusLost();
-
- // part of fix of EXT-996
- // this need to handle event when user click inside in-world area
- mFocusChangeSignal();
}
}
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index 2c2dae216a..2fa4e124fb 100644
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -54,11 +54,12 @@ public:
virtual void setFocus( BOOL b );
virtual BOOL hasFocus() const;
- typedef boost::function<void(LLFocusableElement*, void*)> focus_callback_t;
- void setFocusLostCallback(focus_callback_t cb, void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; }
- void setFocusReceivedCallback(focus_callback_t cb, void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; }
- void setFocusChangedCallback(focus_callback_t cb, void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; }
- void setTopLostCallback(focus_callback_t cb, void* user_data = NULL ) { mTopLostCallback = cb; mFocusCallbackUserData = user_data; }
+ typedef boost::signals2::signal<void(LLFocusableElement*)> focus_signal_t;
+
+ boost::signals2::connection setFocusLostCallback( const focus_signal_t::slot_type& cb) { return mFocusLostCallback.connect(cb);}
+ boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb) { return mFocusReceivedCallback.connect(cb);}
+ boost::signals2::connection setFocusChangedCallback(const focus_signal_t::slot_type& cb) { return mFocusChangedCallback.connect(cb);}
+ void setTopLostCallback(const focus_signal_t::slot_type& cb) { mTopLostCallback.connect(cb);}
// These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
@@ -68,11 +69,10 @@ protected:
virtual void onFocusReceived();
virtual void onFocusLost();
virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
- focus_callback_t mFocusLostCallback;
- focus_callback_t mFocusReceivedCallback;
- focus_callback_t mFocusChangedCallback;
- focus_callback_t mTopLostCallback;
- void* mFocusCallbackUserData;
+ focus_signal_t mFocusLostCallback;
+ focus_signal_t mFocusReceivedCallback;
+ focus_signal_t mFocusChangedCallback;
+ focus_signal_t mTopLostCallback;
};
@@ -124,11 +124,6 @@ public:
void unlockFocus();
BOOL focusLocked() const { return mLockedView != NULL; }
- void addFocusChangeCallback(const boost::signals2::signal<void ()>::slot_type& cb)
- {
- mFocusChangeSignal.connect(cb);
- }
-
private:
LLUICtrl* mLockedView;
@@ -155,8 +150,6 @@ private:
typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t;
focus_history_map_t mFocusHistory;
- boost::signals2::signal<void()> mFocusChangeSignal;
-
#ifdef _DEBUG
std::string mMouseCaptorName;
std::string mKeyboardFocusName;
diff --git a/indra/llui/llhelp.h b/indra/llui/llhelp.h
new file mode 100644
index 0000000000..c06d29a4bd
--- /dev/null
+++ b/indra/llui/llhelp.h
@@ -0,0 +1,45 @@
+/**
+ * @file llhelp.h
+ * @brief Abstract interface to the Help system
+ * @author Tofu Linden
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLHELP_H
+#define LL_LLHELP_H
+
+class LLHelp
+{
+ public:
+ virtual void showTopic(const std::string &topic) = 0;
+ // return default (fallback) topic name suitable for showTopic()
+ virtual std::string defaultTopic() = 0;
+};
+
+#endif // headerguard
diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp
index 01a3b5fdc7..0fbb7ced54 100644
--- a/indra/llui/llmultisliderctrl.cpp
+++ b/indra/llui/llmultisliderctrl.cpp
@@ -140,7 +140,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p)
params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
- mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus );
+ mEditor->setFocusReceivedCallback( boost::bind(LLMultiSliderCtrl::onEditorGainFocus, _1, this) );
// don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others
//mEditor->setSelectAllonFocusReceived(TRUE);
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 26136e0a23..b9bbb4db22 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -80,6 +80,7 @@ LLPanel::Params::Params()
strings("string"),
filename("filename"),
class_name("class"),
+ help_topic("help_topic"),
visible_callback("visible_callback")
{
name = "panel";
@@ -98,6 +99,7 @@ LLPanel::LLPanel(const LLPanel::Params& p)
mDefaultBtn(NULL),
mBorder(NULL),
mLabel(p.label),
+ mHelpTopic(p.help_topic),
mCommitCallbackRegistrar(false),
mEnableCallbackRegistrar(false),
mXMLFilename(p.filename)
@@ -416,6 +418,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
}
setLabel(p.label());
+ setHelpTopic(p.help_topic);
setShape(p.rect);
parseFollowsFlags(p);
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 81b5b68f05..8b23ea7030 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -83,6 +83,7 @@ public:
Optional<std::string> filename;
Optional<std::string> class_name;
+ Optional<std::string> help_topic;
Multiple<LocalizedString> strings;
@@ -139,10 +140,11 @@ public:
void updateDefaultBtn();
void setLabel(const LLStringExplicit& label) { mLabel = label; }
std::string getLabel() const { return mLabel; }
+ void setHelpTopic(const std::string& help_topic) { mHelpTopic = help_topic; }
+ std::string getHelpTopic() const { return mHelpTopic; }
void setCtrlsEnabled(BOOL b);
-
LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
@@ -243,6 +245,8 @@ protected:
EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar;
commit_signal_t mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD()
+
+ std::string mHelpTopic; // the name of this panel's help topic to display in the Help Viewer
private:
LLUIColor mBgColorAlpha;
@@ -259,7 +263,7 @@ private:
// for setting the xml filename when building panel in context dependent cases
std::string mXMLFilename;
-
+
}; // end class LLPanel
#endif
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index 7e72331a3f..7e88b16561 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -130,12 +130,6 @@ public:
void onLineUpBtnPressed(const LLSD& data);
void onLineDownBtnPressed(const LLSD& data);
- void setBGColor(const LLUIColor& color) { mBGColor = color; }
- const LLUIColor& getBGColor() const { return mBGColor; }
-
- void setBGVisible() { mBGVisible = true; }
- bool getBGVisible() const { return mBGVisible; }
-
private:
void updateThumbRect();
void changeLine(S32 delta, BOOL update_thumb );
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index 15584c8dc7..fb71b60725 100644
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -143,7 +143,7 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
line_p.prevalidate_callback(&LLLineEditor::prevalidateFloat);
mEditor = LLUICtrlFactory::create<LLLineEditor>(line_p);
- mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus, this );
+ mEditor->setFocusReceivedCallback( boost::bind(&LLSliderCtrl::onEditorGainFocus, _1, this ));
// don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others
//mEditor->setSelectAllonFocusReceived(TRUE);
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index 3a96bc8f93..83d71006aa 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -142,7 +142,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
- mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this );
+ mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this ));
//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
// than when it doesn't. Instead, if you always have to double click to select all the text,
// it's easier to understand
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 8d5f277b59..39f09b297f 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2001,6 +2001,8 @@ void LLTextEditor::cut()
deleteSelection( FALSE );
needsReflow();
+
+ onKeyStroke();
}
BOOL LLTextEditor::canCopy() const
@@ -2105,6 +2107,8 @@ void LLTextEditor::pasteHelper(bool is_primary)
deselect();
needsReflow();
+
+ onKeyStroke();
}
@@ -2492,6 +2496,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
if(text_may_have_changed)
{
needsReflow();
+
+ onKeyStroke();
}
needsScroll();
}
@@ -2534,6 +2540,8 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
deselect();
needsReflow();
+
+ onKeyStroke();
}
return handled;
@@ -2588,6 +2596,8 @@ void LLTextEditor::doDelete()
setCursorPos(mCursorPos + 1);
removeChar();
}
+
+ onKeyStroke();
}
needsReflow();
@@ -2634,6 +2644,8 @@ void LLTextEditor::undo()
setCursorPos(pos);
needsReflow();
+
+ onKeyStroke();
}
BOOL LLTextEditor::canRedo() const
@@ -2676,6 +2688,8 @@ void LLTextEditor::redo()
setCursorPos(pos);
needsReflow();
+
+ onKeyStroke();
}
void LLTextEditor::onFocusReceived()
@@ -4402,6 +4416,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
// Update of the preedit should be caused by some key strokes.
mKeystrokeTimer.reset();
+
+ onKeyStroke();
}
BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
@@ -4648,3 +4664,30 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
ed->addDocumentChild(mView);
}
}
+
+BOOL LLTextEditor::isDirty() const
+{
+ if(mReadOnly)
+ {
+ return FALSE;
+ }
+
+ if( mPristineCmd )
+ {
+ return ( mPristineCmd == mLastCmd );
+ }
+ else
+ {
+ return ( NULL != mLastCmd );
+ }
+}
+
+void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& callback)
+{
+ mKeystrokeSignal.connect(callback);
+}
+
+void LLTextEditor::onKeyStroke()
+{
+ mKeystrokeSignal(this);
+}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 68b8f2c3b1..a04261c4be 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -139,6 +139,10 @@ public:
virtual ~LLTextEditor();
+ typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
+
+ void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
+
void setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
// mousehandler overrides
@@ -169,7 +173,7 @@ public:
virtual void clear();
virtual void setFocus( BOOL b );
virtual BOOL acceptsTextInput() const;
- virtual BOOL isDirty() const { return isPristine(); }
+ virtual BOOL isDirty() const;
virtual void setValue(const LLSD& value);
// LLEditMenuHandler interface
@@ -503,6 +507,8 @@ private:
S32 getFirstVisibleLine() const;
+ void onKeyStroke();
+
//
// Data
//
@@ -568,6 +574,8 @@ private:
BOOL mHandleEditKeysDirectly;
LLCoordGL mLastIMEPosition; // Last position of the IME editor
+
+ keystroke_signal_t mKeystrokeSignal;
}; // end class LLTextEditor
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 000e85f78c..d5b67f53b7 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -79,10 +79,10 @@ std::list<std::string> gUntranslated;
/*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
/*static*/ LLVector2 LLUI::sGLScaleFactor(1.f, 1.f);
/*static*/ LLWindow* LLUI::sWindow = NULL;
-/*static*/ LLHtmlHelp* LLUI::sHtmlHelp = NULL;
/*static*/ LLView* LLUI::sRootView = NULL;
-/*static*/ BOOL LLUI::sDirty = FALSE;
-/*static*/ LLRect LLUI::sDirtyRect;
+/*static*/ BOOL LLUI::sDirty = FALSE;
+/*static*/ LLRect LLUI::sDirtyRect;
+/*static*/ LLHelp* LLUI::sHelpImpl = NULL;
/*static*/ std::vector<std::string> LLUI::sXUIPaths;
/*static*/ LLFrameTimer LLUI::sMouseIdleTimer;
@@ -695,44 +695,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
}
-void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
- if (NULL == image)
- {
- llwarns << "image == NULL; aborting function" << llendl;
- return;
- }
-
- LLGLSUIDefault gls_ui;
-
- gGL.pushMatrix();
- {
- gGL.translatef((F32)x, (F32)y, 0.f);
-
- gGL.getTexUnit(0)->bind(image);
-
- gGL.color4fv(color.mV);
-
- gGL.begin(LLRender::QUADS);
- {
- gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
- gGL.vertex2i(width, height );
-
- gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
- gGL.vertex2i(0, height );
-
- gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
- gGL.vertex2i(0, 0);
-
- gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
- gGL.vertex2i(width, 0);
- }
- gGL.end();
- }
- gGL.popMatrix();
-}
-
-
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
{
phase = fmod(phase, 1.f);
@@ -1592,6 +1554,9 @@ void LLUI::initClass(const settings_map_t& settings,
// Button initialization callback for toggle buttons
LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
+ // Display the help topic for the current context
+ LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2));
+
// Currently unused, but kept for reference:
LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
@@ -1850,12 +1815,6 @@ LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name)
return NULL;
}
-// static
-void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
-{
- LLUI::sHtmlHelp = html_help;
-}
-
LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
{
for (settings_map_t::iterator itor = sSettingGroups.begin();
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index fddf8192ad..86cb516500 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -57,13 +57,13 @@
#include "llfontgl.h"
class LLColor4;
-class LLHtmlHelp;
class LLVector3;
class LLVector2;
class LLUIImage;
class LLUUID;
class LLWindow;
class LLView;
+class LLHelp;
// UI colors
extern const LLColor4 UI_VERTEX_COLOR;
@@ -104,8 +104,6 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-// Flip vertical, used for LLFloaterHTML
-void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom);
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
@@ -203,7 +201,6 @@ public:
static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
static void screenRectToGL(const LLRect& screen, LLRect *gl);
static void glRectToScreen(const LLRect& gl, LLRect *screen);
- static void setHtmlHelp(LLHtmlHelp* html_help);
// Returns the control group containing the control name, or the default group
static LLControlGroup& getControlControlGroup (const std::string& controlname);
static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); }
@@ -223,8 +220,8 @@ public:
static LLUIAudioCallback sAudioCallback;
static LLVector2 sGLScaleFactor;
static LLWindow* sWindow;
- static LLHtmlHelp* sHtmlHelp;
static LLView* sRootView;
+ static LLHelp* sHelpImpl;
private:
static LLImageProviderInterface* sImageProvider;
static std::vector<std::string> sXUIPaths;
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 8807e26f6b..fe99d9c267 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -114,7 +114,6 @@ void LLUICtrl::initFromParams(const Params& p)
}
setTabStop(p.tab_stop);
- setFocusLostCallback(p.focus_lost_callback());
if (p.initial_value.isProvided()
&& !p.control_name.isProvided())
@@ -763,6 +762,27 @@ LLUICtrl* LLUICtrl::getParentUICtrl() const
return NULL;
}
+bool LLUICtrl::findHelpTopic(std::string& help_topic_out)
+{
+ LLUICtrl* ctrl = this;
+
+ // search back through the control's parents for a panel
+ // with a help_topic string defined
+ while (ctrl)
+ {
+ LLPanel *panel = dynamic_cast<LLPanel *>(ctrl);
+ if (panel && !panel->getHelpTopic().empty())
+ {
+ help_topic_out = panel->getHelpTopic();
+ return true; // success
+ }
+
+ ctrl = ctrl->getParentUICtrl();
+ }
+
+ return false; // no help topic found
+}
+
// *TODO: Deprecate; for backwards compatability only:
boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data)
{
@@ -800,14 +820,7 @@ namespace LLInitParam
return false;
}
- template<>
- bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
- const LLUICtrl::focus_callback_t &a,
- const LLUICtrl::focus_callback_t &b)
- {
- return false;
- }
-
+
template<>
bool ParamCompare<LLUICtrl::enable_callback_t>::equals(
const LLUICtrl::enable_callback_t &a,
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 3add9393ea..c2502732f3 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -124,8 +124,6 @@ public:
Optional<CommitCallbackParam> mouseenter_callback;
Optional<CommitCallbackParam> mouseleave_callback;
- Optional<focus_callback_t> focus_lost_callback;
-
Optional<std::string> control_name;
Optional<EnableControls> enabled_controls;
Optional<ControlVisibility> controls_visibility;
@@ -225,6 +223,10 @@ public:
LLUICtrl* getParentUICtrl() const;
+ // return true if help topic found by crawling through parents -
+ // topic then put in help_topic_out
+ bool findHelpTopic(std::string& help_topic_out);
+
boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); }
boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); }
@@ -309,11 +311,6 @@ namespace LLInitParam
const LLUICtrl::enable_callback_t &a,
const LLUICtrl::enable_callback_t &b);
- template<>
- bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
- const LLUICtrl::focus_callback_t &a,
- const LLUICtrl::focus_callback_t &b);
-
template<>
bool ParamCompare<LLLazyValue<LLColor4> >::equals(
const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b);
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 3b689b93c0..f3401f91f7 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -134,4 +134,3 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel()));
}
}
-
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 256c776293..10cb3fb377 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -466,16 +466,6 @@ LLRect LLView::getRequiredRect()
return mRect;
}
-//virtual
-void LLView::onFocusLost()
-{
-}
-
-//virtual
-void LLView::onFocusReceived()
-{
-}
-
BOOL LLView::focusNextRoot()
{
LLView::child_list_t result = LLView::getFocusRootsQuery().run(this);
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index bf3b5d0614..7a37d6f430 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -405,10 +405,6 @@ public:
BOOL getSaveToXML() const { return mSaveToXML; }
void setSaveToXML(BOOL b) { mSaveToXML = b; }
- // inherited from LLFocusableElement
- /* virtual */ void onFocusLost();
- /* virtual */ void onFocusReceived();
-
typedef enum e_hit_test_type
{
HIT_TEST_USE_BOUNDING_RECT,
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index 24efcb8ae8..7a531e0fbf 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -383,7 +383,7 @@ BOOL LLDir_Linux::fileExists(const std::string &filename) const
/*virtual*/ std::string LLDir_Linux::getLLPluginLauncher()
{
- return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+ return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
"SLPlugin";
}
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index 9be787df11..346f7dd8ed 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -424,7 +424,7 @@ BOOL LLDir_Mac::fileExists(const std::string &filename) const
/*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
{
- return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+ return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() +
"SLPlugin";
}
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 872f2cf1c1..3e302764de 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -397,7 +397,7 @@ BOOL LLDir_Win32::fileExists(const std::string &filename) const
/*virtual*/ std::string LLDir_Win32::getLLPluginLauncher()
{
- return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+ return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
"SLPlugin.exe";
}
diff --git a/indra/lscript/lscript_compile/CMakeLists.txt b/indra/lscript/lscript_compile/CMakeLists.txt
index 252085bab2..3ed2892e0e 100644
--- a/indra/lscript/lscript_compile/CMakeLists.txt
+++ b/indra/lscript/lscript_compile/CMakeLists.txt
@@ -5,6 +5,7 @@ include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLInventory)
+include(LLPrimitive)
include(LScript)
include(FindCygwin)
@@ -41,6 +42,7 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
+ ${LLPRIMITIVE_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
)
diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l
index 9cc2841e8c..8c891b3e8f 100644
--- a/indra/lscript/lscript_compile/indra.l
+++ b/indra/lscript/lscript_compile/indra.l
@@ -34,6 +34,7 @@ FS (f|F)
#include "llregionflags.h"
#include "lscript_http.h"
#include "llclickaction.h"
+#include "llmediaentry.h"
void count();
void line_comment();
@@ -233,7 +234,8 @@ extern "C" { int yyerror(const char *fmt, ...); }
"CHANGED_OWNER" { count(); yylval.ival = CHANGED_OWNER; return(INTEGER_CONSTANT); }
"CHANGED_REGION" { count(); yylval.ival = CHANGED_REGION; return(INTEGER_CONSTANT); }
"CHANGED_TELEPORT" { count(); yylval.ival = CHANGED_TELEPORT; return(INTEGER_CONSTANT); }
-"CHANGED_REGION_START" { count(); yylval.ival = CHANGED_REGION_START; return(INTEGER_CONSTANT); }
+"CHANGED_REGION_START" { count(); yylval.ival = CHANGED_REGION_START; return(INTEGER_CONSTANT); }
+"CHANGED_MEDIA" { count(); yylval.ival = CHANGED_MEDIA; return(INTEGER_CONSTANT); }
"OBJECT_UNKNOWN_DETAIL" { count(); yylval.ival = OBJECT_UNKNOWN_DETAIL; return(INTEGER_CONSTANT); }
"OBJECT_NAME" { count(); yylval.ival = OBJECT_NAME; return(INTEGER_CONSTANT); }
@@ -622,6 +624,45 @@ extern "C" { int yyerror(const char *fmt, ...); }
"TOUCH_INVALID_VECTOR" { count(); return(TOUCH_INVALID_VECTOR); }
"TOUCH_INVALID_TEXCOORD" { count(); return(TOUCH_INVALID_TEXCOORD); }
+"PRIM_MEDIA_ALT_IMAGE_ENABLE" { count(); yylval.ival = LLMediaEntry::ALT_IMAGE_ENABLE_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_CONTROLS" { count(); yylval.ival = LLMediaEntry::CONTROLS_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_CURRENT_URL" { count(); yylval.ival = LLMediaEntry::CURRENT_URL_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_HOME_URL" { count(); yylval.ival = LLMediaEntry::HOME_URL_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_AUTO_LOOP" { count(); yylval.ival = LLMediaEntry::AUTO_LOOP_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_AUTO_PLAY" { count(); yylval.ival = LLMediaEntry::AUTO_PLAY_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_AUTO_SCALE" { count(); yylval.ival = LLMediaEntry::AUTO_SCALE_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_AUTO_ZOOM" { count(); yylval.ival = LLMediaEntry::AUTO_ZOOM_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_FIRST_CLICK_INTERACT" { count(); yylval.ival = LLMediaEntry::FIRST_CLICK_INTERACT_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_WIDTH_PIXELS" { count(); yylval.ival = LLMediaEntry::WIDTH_PIXELS_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_HEIGHT_PIXELS" { count(); yylval.ival = LLMediaEntry::HEIGHT_PIXELS_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_WHITELIST_ENABLE" { count(); yylval.ival = LLMediaEntry::WHITELIST_ENABLE_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_WHITELIST" { count(); yylval.ival = LLMediaEntry::WHITELIST_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PERMS_INTERACT" { count(); yylval.ival = LLMediaEntry::PERMS_INTERACT_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PERMS_CONTROL" { count(); yylval.ival = LLMediaEntry::PERMS_CONTROL_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PARAM_MAX" { count(); yylval.ival = LLMediaEntry::PARAM_MAX_ID; return(INTEGER_CONSTANT); }
+
+"PRIM_MEDIA_CONTROLS_STANDARD" { count(); yylval.ival = LLMediaEntry::STANDARD; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_CONTROLS_MINI" { count(); yylval.ival = LLMediaEntry::MINI; return(INTEGER_CONSTANT); }
+
+"PRIM_MEDIA_PERM_NONE" { count(); yylval.ival = LLMediaEntry::PERM_NONE; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PERM_OWNER" { count(); yylval.ival = LLMediaEntry::PERM_OWNER; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PERM_GROUP" { count(); yylval.ival = LLMediaEntry::PERM_GROUP; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PERM_ANYONE" { count(); yylval.ival = LLMediaEntry::PERM_ANYONE; return(INTEGER_CONSTANT); }
+
+"PRIM_MEDIA_MAX_URL_LENGTH" { count(); yylval.ival = LLMediaEntry::MAX_URL_LENGTH; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_MAX_WHITELIST_SIZE" { count(); yylval.ival = LLMediaEntry::MAX_WHITELIST_SIZE; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_MAX_WHITELIST_COUNT" { count(); yylval.ival = LLMediaEntry::MAX_WHITELIST_COUNT; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_MAX_WIDTH_PIXELS" { count(); yylval.ival = LLMediaEntry::MAX_WIDTH_PIXELS; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_MAX_HEIGHT_PIXELS" { count(); yylval.ival = LLMediaEntry::MAX_HEIGHT_PIXELS; return(INTEGER_CONSTANT); }
+
+"STATUS_OK" { count(); yylval.ival = LSL_STATUS_OK; return(INTEGER_CONSTANT); }
+"STATUS_MALFORMED_PARAMS" { count(); yylval.ival = LSL_STATUS_MALFORMED_PARAMS; return(INTEGER_CONSTANT); }
+"STATUS_TYPE_MISMATCH" { count(); yylval.ival = LSL_STATUS_TYPE_MISMATCH; return(INTEGER_CONSTANT); }
+"STATUS_BOUNDS_ERROR" { count(); yylval.ival = LSL_STATUS_BOUNDS_ERROR; return(INTEGER_CONSTANT); }
+"STATUS_NOT_FOUND" { count(); yylval.ival = LSL_STATUS_NOT_FOUND; return(INTEGER_CONSTANT); }
+"STATUS_NOT_SUPPORTED" { count(); yylval.ival = LSL_STATUS_NOT_SUPPORTED; return(INTEGER_CONSTANT); }
+"STATUS_INTERNAL_ERROR" { count(); yylval.ival = LSL_STATUS_INTERNAL_ERROR; return(INTEGER_CONSTANT); }
+"STATUS_WHITELIST_FAILED" { count(); yylval.ival = LSL_STATUS_WHITELIST_FAILED; return(INTEGER_CONSTANT); }
{L}({L}|{N})* { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(IDENTIFIER); }
diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp
index 0d51c27c92..5e394644c2 100644
--- a/indra/lscript/lscript_library/lscript_library.cpp
+++ b/indra/lscript/lscript_library/lscript_library.cpp
@@ -450,7 +450,12 @@ void LLScriptLibrary::init()
addFunction(10.f, 0.f, dummy_func, "llHTTPResponse", NULL, "kis");
addFunction(10.f, 0.f, dummy_func, "llGetHTTPHeader", "s", "ks");
- // energy, sleep, dummy_func, name, return type, parameters, gods-only
+ // Prim media (see lscript_prim_media.h)
+ addFunction(10.f, 1.0f, dummy_func, "llSetPrimMediaParams", "i", "il");
+ addFunction(10.f, 1.0f, dummy_func, "llGetPrimMediaParams", "l", "il");
+ addFunction(10.f, 1.0f, dummy_func, "llClearPrimMedia", "i", "i");
+
+ // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only
// IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST.
// Otherwise the bytecode numbers for each call will be wrong, and all
@@ -495,7 +500,7 @@ void LLScriptLibData::print(std::ostream &s, BOOL b_prepend_comma)
s << ", ";
}
switch (mType)
- {
+ {
case LST_INTEGER:
s << mInteger;
break;
diff --git a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
index 647db7a5bf..a4c43988ba 100644
--- a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
+++ b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
@@ -975,10 +975,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
- U64 address_lo = message_in.getValueU32("address");
- U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
- info.mAddress = (void*)((address_lo) |
- (address_hi * (U64(1)<<31)));
+ info.mAddress = message_in.getValuePointer("address");
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");
diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
index e9be458960..fbda65120d 100644
--- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
+++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
@@ -772,10 +772,7 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string)
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
- U64 address_lo = message_in.getValueU32("address");
- U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
- info.mAddress = (void*)((address_lo) |
- (address_hi * (U64(1)<<31)));
+ info.mAddress = message_in.getValuePointer("address");
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
index 2928b7e6b3..eb2457744a 100644
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
@@ -147,8 +147,11 @@ private:
#if LL_WINDOWS
// Enable plugins
- LLQtWebKit::getInstance()->enablePlugins(true);
-#else
+ LLQtWebKit::getInstance()->enablePlugins(false);
+#elif LL_DARWIN
+ // Disable plugins
+ LLQtWebKit::getInstance()->enablePlugins(false);
+#elif LL_LINUX
// Disable plugins
LLQtWebKit::getInstance()->enablePlugins(false);
#endif
@@ -164,6 +167,11 @@ private:
// don't flip bitmap
LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true );
+
+ // Set the background color to black
+ LLQtWebKit::getInstance()->
+ // set background color to be black - mostly for initial login page
+ LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, 0x00, 0x00, 0x00 );
// go to the "home page"
// Don't do this here -- it causes the dreaded "white flash" when loading a browser instance.
@@ -483,8 +491,8 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
mDepth = 4;
message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
- message.setValueS32("default_width", 800);
- message.setValueS32("default_height", 600);
+ message.setValueS32("default_width", 1024);
+ message.setValueS32("default_height", 1024);
message.setValueS32("depth", mDepth);
message.setValueU32("internalformat", GL_RGBA);
message.setValueU32("format", GL_RGBA);
@@ -507,10 +515,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
- U64 address_lo = message_in.getValueU32("address");
- U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
- info.mAddress = (void*)((address_lo) |
- (address_hi * (U64(1)<<31)));
+ info.mAddress = message_in.getValuePointer("address");
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 7b707a6720..4482a75405 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -169,9 +169,9 @@ set(viewer_SOURCE_FILES
llfloatergroups.cpp
llfloaterhandler.cpp
llfloaterhardwaresettings.cpp
- llfloaterhtmlcurrency.cpp
+ llfloaterhelpbrowser.cpp
llfloatermediabrowser.cpp
- llfloaterhtmlsimple.cpp
+ llfloatermediasettings.cpp
llfloaterhud.cpp
llfloaterimagepreview.cpp
llfloaterinspect.cpp
@@ -208,6 +208,7 @@ set(viewer_SOURCE_FILES
llfloaterurlentry.cpp
llfloatervoicedevicesettings.cpp
llfloaterwater.cpp
+ llfloaterwhitelistentry.cpp
llfloaterwindlight.cpp
llfloaterworldmap.cpp
llfoldertype.cpp
@@ -260,6 +261,9 @@ set(viewer_SOURCE_FILES
llmanipscale.cpp
llmaniptranslate.cpp
llmapresponders.cpp
+ llmediactrl.cpp
+ llmediadataresponder.cpp
+ llmediadatafetcher.cpp
llmediaremotectrl.cpp
llmemoryview.cpp
llmenucommands.cpp
@@ -321,6 +325,9 @@ set(viewer_SOURCE_FILES
llpanelmediahud.cpp
llpanelmeprofile.cpp
llpanelmovetip.cpp
+ llpanelmediasettingsgeneral.cpp
+ llpanelmediasettingssecurity.cpp
+ llpanelmediasettingspermissions.cpp
llpanelobject.cpp
llpanelpeople.cpp
llpanelpeoplemenus.cpp
@@ -426,6 +433,8 @@ set(viewer_SOURCE_FILES
llviewerfloaterreg.cpp
llviewergenericmessage.cpp
llviewergesture.cpp
+ llviewerhelp.cpp
+ llviewerhelputil.cpp
llviewerinventory.cpp
llviewerjointattachment.cpp
llviewerjoint.cpp
@@ -490,7 +499,6 @@ set(viewer_SOURCE_FILES
llwearabledictionary.cpp
llwearablelist.cpp
llweb.cpp
- llmediactrl.cpp
llwind.cpp
llwlanimator.cpp
llwldaycycle.cpp
@@ -632,9 +640,9 @@ set(viewer_HEADER_FILES
llfloatergroups.h
llfloaterhandler.h
llfloaterhardwaresettings.h
- llfloaterhtmlcurrency.h
+ llfloaterhelpbrowser.h
llfloatermediabrowser.h
- llfloaterhtmlsimple.h
+ llfloatermediasettings.h
llfloaterhud.h
llfloaterimagepreview.h
llfloaterinspect.h
@@ -671,6 +679,7 @@ set(viewer_HEADER_FILES
llfloaterurlentry.h
llfloatervoicedevicesettings.h
llfloaterwater.h
+ llfloaterwhitelistentry.h
llfloaterwindlight.h
llfloaterworldmap.h
llfoldertype.h
@@ -723,6 +732,8 @@ set(viewer_HEADER_FILES
llmanipscale.h
llmaniptranslate.h
llmapresponders.h
+ llmediadataresponder.h
+ llmediadatafetcher.h
llmediaremotectrl.h
llmemoryview.h
llmenucommands.h
@@ -781,6 +792,9 @@ set(viewer_HEADER_FILES
llpanelmediahud.h
llpanelmeprofile.h
llpanelmovetip.h
+ llpanelmediasettingsgeneral.h
+ llpanelmediasettingssecurity.h
+ llpanelmediasettingspermissions.h
llpanelobject.h
llpanelpeople.h
llpanelpeoplemenus.h
@@ -891,6 +905,7 @@ set(viewer_HEADER_FILES
llviewerfloaterreg.h
llviewergenericmessage.h
llviewergesture.h
+ llviewerhelp.h
llviewerinventory.h
llviewerjoint.h
llviewerjointattachment.h
@@ -1526,6 +1541,7 @@ endif (INSTALL)
include(LLAddBuildTest)
SET(viewer_TEST_SOURCE_FILES
llagentaccess.cpp
+ llviewerhelputil.cpp
)
set_source_files_properties(
${viewer_TEST_SOURCE_FILES}
@@ -1565,7 +1581,7 @@ if (WINDOWS)
-E
copy_if_different
${BUILT_SLPLUGIN}
- ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
COMMENT "Copying SLPlugin executable to the runtime folder."
)
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini
index eaf5213985..5d52158298 100644
--- a/indra/newview/app_settings/keywords.ini
+++ b/indra/newview/app_settings/keywords.ini
@@ -40,14 +40,14 @@ not_at_rot_target not_at_rot_target():Result of LLRotTarget library function cal
money money(key id, integer amount):Triggered when L$ is given to task
email email(string time, string address, string subj, string message, integer num_left):Triggered when task receives email
run_time_permissions run_time_permissions(integer perm):Triggered when an agent grants run time permissions to task
-attach attach(key id):Triggered when an agent attaches or detaches from agent
+attach attach(key id):Triggered when task attaches or detaches from agent
dataserver dataserver(key queryid, string data):Triggered when task receives asynchronous data
moving_start moving_start():Triggered when task begins moving
moving_end moving_end():Triggered when task stops moving
on_rez on_rez(integer start_param):Triggered when task is rezed in from inventory or another task
object_rez object_rez(key id):Triggered when task rezes in another task
link_message link_message(integer sender_num, integer num, string str, key id):Triggered when task receives a link message via LLMessageLinked library function call
-changed changed( integer change ):Triggered various event change the task:(test change with CHANGED_INVENTORY, CHANGED_COLOR, CHANGED_SHAPE, CHANGED_SCALE, CHANGED_TEXTURE, CHANGED_LINK, CHANGED_ALLOWED_DROP, CHANGED_OWNER, CHANGED_REGION, CHANGED_TELEPORT)
+changed changed( integer change ):Triggered various event change the task:(test change with CHANGED_INVENTORY, CHANGED_COLOR, CHANGED_SHAPE, CHANGED_SCALE, CHANGED_TEXTURE, CHANGED_LINK, CHANGED_ALLOWED_DROP, CHANGED_OWNER, CHANGED_REGION, CHANGED_TELEPORT, CHANGED_REGION_START, CHANGED_MEDIA)
remote_data remote_data(integer event_type, key channel, key message_id, string sender,integer idata, string sdata):Triggered by various XML-RPC calls (event_type will be one of REMOTE_DATA_CHANNEL, REMOTE_DATA_REQUEST, REMOTE_DATA_REPLY)
http_response http_response(key request_id, integer status, list metadata, string body):Triggered when task receives a response to one of its llHTTPRequests
http_request http_request(key id, string method, string body):Triggered when task receives an http request against a public URL
@@ -320,6 +320,7 @@ CHANGED_OWNER Parameter of changed event handler used to indicate change to tas
CHANGED_REGION Parameter of changed event handler used to indicate the region has changed
CHANGED_TELEPORT Parameter of changed event handler used to indicate teleport has completed
CHANGED_REGION_START Parameter of changed event handler used to indicate the region has been restarted
+CHANGED_MEDIA Parameter of changed event handler used to indicate that media has changed on a face of the task
TYPE_INTEGER Indicates that the list entry is holding an integer
TYPE_FLOAT Indicates that the list entry is holding an float
@@ -513,6 +514,46 @@ TOUCH_INVALID_TEXCOORD Value returned by llDetectedTouchUV() and llDetectedTouc
TOUCH_INVALID_VECTOR Value returned by llDetectedTouchPos(), llDetectedTouchNormal(), and llDetectedTouchBinormal() when the touch position is not valid.
TOUCH_INVALID_FACE Value returned by llDetectedTouchFace() when the touch position is not valid.
+PRIM_MEDIA_ALT_IMAGE_ENABLE Used with ll{Get,Set}PrimMediaParams to enable the default alt image for media
+PRIM_MEDIA_CONTROLS Used with ll{Get,Set}PrimMediaParams to determine the controls shown for media
+PRIM_MEDIA_CURRENT_URL Used with ll{Get,Set}PrimMediaParams to navigate/access the current URL
+PRIM_MEDIA_HOME_URL Used with ll{Get,Set}PrimMediaParams to access the home URL
+PRIM_MEDIA_AUTO_LOOP Used with ll{Get,Set}PrimMediaParams to determine if media should auto-loop (if applicable)
+PRIM_MEDIA_AUTO_PLAY Used with ll{Get,Set}PrimMediaParams to determine if media should start playing as soon as it is created
+PRIM_MEDIA_AUTO_SCALE Used with ll{Get,Set}PrimMediaParams to determine if media should scale to fit the face it is on
+PRIM_MEDIA_AUTO_ZOOM Used with ll{Get,Set}PrimMediaParams to determine if the user would zoom in when viewing media
+PRIM_MEDIA_FIRST_CLICK_INTERACT Used with ll{Get,Set}PrimMediaParams to determine whether the user interacts with media or not when she first clicks it (versus selection)
+PRIM_MEDIA_WIDTH_PIXELS Used with ll{Get,Set}PrimMediaParams to access the media's width in pixels
+PRIM_MEDIA_HEIGHT_PIXELS Used with ll{Get,Set}PrimMediaParams to access the media's height in pixels
+PRIM_MEDIA_WHITELIST_ENABLE Used with ll{Get,Set}PrimMediaParams to determine if the domain whitelist is enabled
+PRIM_MEDIA_WHITELIST Used with ll{Get,Set}PrimMediaParams to access the media's list of allowable URL prefixes to navigate to
+PRIM_MEDIA_PERMS_INTERACT Used with ll{Get,Set}PrimMediaParams to determine the permissions for who can interact with the media
+PRIM_MEDIA_PERMS_CONTROL Used with ll{Get,Set}PrimMediaParams to determine the permissions for who has controls
+PRIM_MEDIA_PARAM_MAX The value of the largest media param
+
+PRIM_MEDIA_CONTROLS_STANDARD Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_CONTROLS value meaning "standard controls"
+PRIM_MEDIA_CONTROLS_MINI Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_CONTROLS value meaning "mini controls"
+
+PRIM_MEDIA_PERM_NONE Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, no permissions
+PRIM_MEDIA_PERM_OWNER Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, owner permissions
+PRIM_MEDIA_PERM_GROUP Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, group permissions
+PRIM_MEDIA_PERM_ANYONE Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, anyone has permissions
+
+PRIM_MEDIA_MAX_URL_LENGTH Used with ll{Get,Set}PrimMediaParams, the maximum length of PRIM_MEDIA_CURRENT_URL or PRIM_MEDIA_HOME_URL
+PRIM_MEDIA_MAX_WHITELIST_SIZE Used with ll{Get,Set}PrimMediaParams, the maximum length, in bytes, of PRIM_MEDIA_WHITELIST
+PRIM_MEDIA_MAX_WHITELIST_COUNT Used with ll{Get,Set}PrimMediaParams, the maximum number of items allowed in PRIM_MEDIA_WHITELIST
+PRIM_MEDIA_MAX_WIDTH_PIXELS Used with ll{Get,Set}PrimMediaParams, the maximum width allowed in PRIM_MEDIA_WIDTH_PIXELS
+PRIM_MEDIA_MAX_HEIGHT_PIXELS Used with ll{Get,Set}PrimMediaParams, the maximum width allowed in PRIM_MEDIA_HEIGHT_PIXELS
+
+STATUS_OK Result of function call was success
+STATUS_MALFORMED_PARAMS Function was called with malformed params
+STATUS_TYPE_MISMATCH Argument(s) passed to function had a type mismatch
+STATUS_BOUNDS_ERROR Argument(s) passed to function had a bounds error
+STATUS_NOT_FOUND Object or other item was not found
+STATUS_NOT_SUPPORTED Feature not supported
+STATUS_INTERNAL_ERROR An internal error occurred
+STATUS_WHITELIST_FAILED URL failed to pass whitelist
+
# string constants
[word .1, .3, .5]
NULL_KEY Indicates an empty key
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 19d503390c..99b662a63f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -3542,28 +3542,28 @@
<string>S32</string>
<key>Value</key>
<integer>400</integer>
- </map>
- <key>HelpHomeURL</key>
+ </map>
+ <key>HelpUseLocal</key>
<map>
<key>Comment</key>
- <string>URL of initial help page</string>
+ <string>If set, always use this for help: skins/default/html/[LANGUAGE]/help-offline/index.html</string>
<key>Persist</key>
- <integer>1</integer>
+ <integer>0</integer>
<key>Type</key>
- <string>String</string>
+ <string>Boolean</string>
<key>Value</key>
- <string>help/index.html</string>
+ <integer>0</integer>
</map>
- <key>HelpLastVisitedURL</key>
+ <key>HelpURLFormat</key>
<map>
<key>Comment</key>
- <string>URL of last help page, will be shown next time help is accessed</string>
+ <string>URL pattern for help page; arguments will be encoded; see llviewerhelp.cpp:buildHelpURL for arguments</string>
<key>Persist</key>
- <integer>1</integer>
+ <integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>help/index.html</string>
+ <string>http://www.google.com/search?q=site%3Awiki.secondlife.com+[TOPIC]&amp;ignore_channel=[CHANNEL]&amp;ignore_version=[VERSION]&amp;ignore_os=[OS]&amp;ignore_language=[LANGUAGE]&amp;ignore_version_major=[VERSION_MAJOR]&amp;ignore_version_minor=[VERSION_MINOR]&amp;ignore_version_patch=[VERSION_PATCH]&amp;ignore_version_build=[VERSION_BUILD]</string>
</map>
<key>HighResSnapshot</key>
<map>
@@ -3994,6 +3994,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>LastMediaSettingsTab</key>
+ <map>
+ <key>Comment</key>
+ <string>Last selected tab in media settings window</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>LastRunVersion</key>
<map>
<key>Comment</key>
@@ -4455,7 +4466,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>MemoryLogFrequency</key>
<map>
@@ -5216,6 +5227,51 @@
<key>Value</key>
<integer>1</integer>
</map>
+
+ <key>PluginInstancesCPULimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Amount of total plugin CPU usage before inworld plugins start getting turned down to "slideshow" priority. Set to 0 to disable this check.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
+ <key>PluginInstancesLow</key>
+ <map>
+ <key>Comment</key>
+ <string>Limit on the number of inworld media plugins that will run at "low" priority</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>4</integer>
+ </map>
+ <key>PluginInstancesNormal</key>
+ <map>
+ <key>Comment</key>
+ <string>Limit on the number of inworld media plugins that will run at "normal" priority</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>4</integer>
+ </map>
+ <key>PluginInstancesTotal</key>
+ <map>
+ <key>Comment</key>
+ <string>Hard limit on the number of plugins that will be instantiated at once</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>16</integer>
+ </map>
<key>PrecachingDelay</key>
<map>
<key>Comment</key>
@@ -5238,6 +5294,28 @@
<key>Value</key>
<integer>13</integer>
</map>
+ <key>PrimMediaFetchQueueDelay</key>
+ <map>
+ <key>Comment</key>
+ <string>Timer delay for fetching media from the queue (in seconds).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>PrimMediaRetryTimerDelay</key>
+ <map>
+ <key>Comment</key>
+ <string>Timer delay for retrying on media queries (in seconds).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>5.0</real>
+ </map>
<key>ProbeHardwareOnStartup</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 355660faa5..30e0a5770c 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -67,6 +67,7 @@
#include "llviewerobjectlist.h"
#include "llworldmap.h"
#include "llmutelist.h"
+#include "llviewerhelp.h"
#include "lluicolortable.h"
#include "llurldispatcher.h"
#include "llurlhistory.h"
@@ -663,8 +664,6 @@ bool LLAppViewer::init()
mNumSessions++;
gSavedSettings.setS32("NumSessions", mNumSessions);
- gSavedSettings.setString("HelpLastVisitedURL",gSavedSettings.getString("HelpHomeURL"));
-
if (gSavedSettings.getBOOL("VerboseLogs"))
{
LLError::setPrintLocation(true);
@@ -694,6 +693,9 @@ bool LLAppViewer::init()
LLUrlAction::setOpenURLExternalCallback(&LLWeb::loadURLExternal);
LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor);
+ // Let code in llui access the viewer help floater
+ LLUI::sHelpImpl = LLViewerHelp::getInstance();
+
// Set the link color for any Urls in text fields
LLTextBase::setLinkColor( LLUIColorTable::instance().getColor("HTMLLinkColor") );
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index ee14a2ff86..36f9780ad0 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -41,6 +41,10 @@
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
+// Maximum number of avatars that can be added to a list in one pass.
+// Used to limit time spent for avatar list update per frame.
+static const unsigned ADD_LIMIT = 50;
+
static bool findInsensitive(std::string haystack, const std::string& needle_upper)
{
LLStringUtil::toUpper(haystack);
@@ -65,6 +69,7 @@ LLAvatarList::LLAvatarList(const Params& p)
: LLFlatListView(p)
, mOnlineGoFirst(p.online_go_first)
, mContextMenu(NULL)
+, mDirty(true) // to force initial update
{
setCommitOnSelectionChange(true);
@@ -72,44 +77,40 @@ LLAvatarList::LLAvatarList(const Params& p)
setComparator(&NAME_COMPARATOR);
}
-void LLAvatarList::computeDifference(
- const std::vector<LLUUID>& vnew_unsorted,
- std::vector<LLUUID>& vadded,
- std::vector<LLUUID>& vremoved)
+// virtual
+void LLAvatarList::draw()
{
- std::vector<LLUUID> vcur;
- std::vector<LLUUID> vnew = vnew_unsorted;
+ if (mDirty)
+ refresh();
- // Convert LLSDs to LLUUIDs.
- {
- std::vector<LLSD> vcur_values;
- getValues(vcur_values);
+ LLFlatListView::draw();
+}
- for (size_t i=0; i<vcur_values.size(); i++)
- vcur.push_back(vcur_values[i].asUUID());
+void LLAvatarList::setNameFilter(const std::string& filter)
+{
+ if (mNameFilter != filter)
+ {
+ mNameFilter = filter;
+ setDirty();
}
+}
- std::sort(vcur.begin(), vcur.end());
- std::sort(vnew.begin(), vnew.end());
-
- std::vector<LLUUID>::iterator it;
- size_t maxsize = llmax(vcur.size(), vnew.size());
- vadded.resize(maxsize);
- vremoved.resize(maxsize);
-
- // what to remove
- it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
- vremoved.erase(it, vremoved.end());
-
- // what to add
- it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
- vadded.erase(it, vadded.end());
+void LLAvatarList::sortByName()
+{
+ setComparator(&NAME_COMPARATOR);
+ sort();
}
-BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
+//////////////////////////////////////////////////////////////////////////
+// PROTECTED SECTION
+//////////////////////////////////////////////////////////////////////////
+
+void LLAvatarList::refresh()
{
- BOOL have_names = TRUE;
- bool have_filter = name_filter != LLStringUtil::null;
+ bool have_names = TRUE;
+ bool add_limit_exceeded = false;
+ bool modified = false;
+ bool have_filter = !mNameFilter.empty();
// Save selection.
std::vector<LLUUID> selected_ids;
@@ -118,22 +119,36 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
// Determine what to add and what to remove.
std::vector<LLUUID> added, removed;
- LLAvatarList::computeDifference(all_buddies, added, removed);
+ LLAvatarList::computeDifference(getIDs(), added, removed);
// Handle added items.
+ unsigned nadded = 0;
for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
{
std::string name;
const LLUUID& buddy_id = *it;
- have_names &= gCacheName->getFullName(buddy_id, name);
- if (!have_filter || findInsensitive(name, name_filter))
- addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+ have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+ if (!have_filter || findInsensitive(name, mNameFilter))
+ {
+ if (nadded >= ADD_LIMIT)
+ {
+ add_limit_exceeded = true;
+ break;
+ }
+ else
+ {
+ addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+ modified = true;
+ nadded++;
+ }
+ }
}
// Handle removed items.
for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
{
removeItemByUUID(*it);
+ modified = true;
}
// Handle filter.
@@ -146,9 +161,12 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
{
std::string name;
const LLUUID& buddy_id = it->asUUID();
- have_names &= gCacheName->getFullName(buddy_id, name);
- if (!findInsensitive(name, name_filter))
+ have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+ if (!findInsensitive(name, mNameFilter))
+ {
removeItemByUUID(buddy_id);
+ modified = true;
+ }
}
}
@@ -167,18 +185,15 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
//
// Otherwise, if we have no filter then no need to update again
// because the items will update their names.
- return !have_filter || have_names;
-}
+ bool dirty = add_limit_exceeded || (have_filter && !have_names);
+ setDirty(dirty);
-void LLAvatarList::sortByName()
-{
- setComparator(&NAME_COMPARATOR);
- sort();
+ // Commit if we've added/removed items.
+ if (modified)
+ onCommit();
}
-//////////////////////////////////////////////////////////////////////////
-// PROTECTED SECTION
-//////////////////////////////////////////////////////////////////////////
+
void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
{
LLAvatarListItem* item = new LLAvatarListItem();
@@ -194,8 +209,39 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
addItem(item, id, pos);
}
+void LLAvatarList::computeDifference(
+ const std::vector<LLUUID>& vnew_unsorted,
+ std::vector<LLUUID>& vadded,
+ std::vector<LLUUID>& vremoved)
+{
+ std::vector<LLUUID> vcur;
+ std::vector<LLUUID> vnew = vnew_unsorted;
+ // Convert LLSDs to LLUUIDs.
+ {
+ std::vector<LLSD> vcur_values;
+ getValues(vcur_values);
+ for (size_t i=0; i<vcur_values.size(); i++)
+ vcur.push_back(vcur_values[i].asUUID());
+ }
+
+ std::sort(vcur.begin(), vcur.end());
+ std::sort(vnew.begin(), vnew.end());
+
+ std::vector<LLUUID>::iterator it;
+ size_t maxsize = llmax(vcur.size(), vnew.size());
+ vadded.resize(maxsize);
+ vremoved.resize(maxsize);
+
+ // what to remove
+ it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
+ vremoved.erase(it, vremoved.end());
+
+ // what to add
+ it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
+ vadded.erase(it, vadded.end());
+}
bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
{
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 8d79e073d2..ec801645fe 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -37,10 +37,22 @@
#include "llavatarlistitem.h"
+/**
+ * Generic list of avatars.
+ *
+ * Updates itself when it's dirty, using optional name filter.
+ * To initiate update, modify the UUID list and call setDirty().
+ *
+ * @see getIDs()
+ * @see setDirty()
+ * @see setNameFilter()
+ */
class LLAvatarList : public LLFlatListView
{
LOG_CLASS(LLAvatarList);
public:
+ typedef std::vector<LLUUID> uuid_vector_t;
+
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
{
Optional<S32> volume_column_width;
@@ -51,14 +63,19 @@ public:
LLAvatarList(const Params&);
virtual ~LLAvatarList() {}
- BOOL update(const std::vector<LLUUID>& all_buddies,
- const std::string& name_filter = LLStringUtil::null);
+ virtual void draw(); // from LLView
+
+ void setNameFilter(const std::string& filter);
+ void setDirty(bool val = true) { mDirty = val; }
+ uuid_vector_t& getIDs() { return mIDs; }
void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; }
void sortByName();
protected:
+ void refresh();
+
void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
void computeDifference(
const std::vector<LLUUID>& vnew,
@@ -68,6 +85,10 @@ protected:
private:
bool mOnlineGoFirst;
+ bool mDirty;
+
+ std::string mNameFilter;
+ uuid_vector_t mIDs;
LLAvatarListItem::ContextMenu* mContextMenu;
};
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 46151b469f..8771611b1c 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -133,6 +133,7 @@ LLIMChiclet* LLBottomTray::createIMChiclet(const LLUUID& session_id)
case LLIMChiclet::TYPE_IM:
return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
case LLIMChiclet::TYPE_GROUP:
+ case LLIMChiclet::TYPE_AD_HOC:
return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
case LLIMChiclet::TYPE_UNKNOWN:
break;
@@ -231,7 +232,7 @@ void LLBottomTray::showBottomTrayContextMenu(S32 x, S32 y, MASK mask)
mBottomTrayContextMenu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, mBottomTrayContextMenu, x, y);
- }
+ }
}
void LLBottomTray::showGestureButton(BOOL visible)
@@ -243,7 +244,7 @@ void LLBottomTray::showGestureButton(BOOL visible)
mGestureCombo->setVisible(visible);
if (!visible)
- {
+ {
LLFloaterReg::hideFloaterInstance("gestures");
r.mRight -= mGestureCombo->getRect().getWidth();
}
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 7ae9976338..c4619dc57a 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -77,7 +77,7 @@ LLScreenChannel* LLChannelManager::createNotificationChannel()
p.channel_align = CA_RIGHT;
// Getting a Channel for our notifications
- return LLChannelManager::getInstance()->getChannel(p);
+ return dynamic_cast<LLScreenChannel*> (LLChannelManager::getInstance()->getChannel(p));
}
//--------------------------------------------------------------------------
@@ -113,7 +113,7 @@ void LLChannelManager::onLoginCompleted()
LLChannelManager::Params p;
p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
p.channel_align = CA_RIGHT;
- mStartUpChannel = getChannel(p);
+ mStartUpChannel = createChannel(p);
if(!mStartUpChannel)
{
@@ -147,22 +147,32 @@ void LLChannelManager::onStartUpToastClose()
LLScreenChannel::setStartUpToastShown();
// force NEARBY CHAT CHANNEL to repost all toasts if present
- LLScreenChannel* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
- nearby_channel->loadStoredToastsToChannel();
- nearby_channel->setCanStoreToasts(false);
+ //LLScreenChannelBase* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+ //!!!!!!!!!!!!!!
+ //FIXME
+ //nearby_channel->loadStoredToastsToChannel();
+ //nearby_channel->setCanStoreToasts(false);
}
//--------------------------------------------------------------------------
-LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
+
+LLScreenChannelBase* LLChannelManager::addChannel(LLScreenChannelBase* channel)
{
- LLScreenChannel* new_channel = NULL;
+ if(!channel)
+ return 0;
- new_channel = findChannelByID(p.id);
+ ChannelElem new_elem;
+ new_elem.id = channel->getChannelID();
+ new_elem.channel = channel;
- if(new_channel)
- return new_channel;
+ mChannelList.push_back(new_elem);
- new_channel = new LLScreenChannel(p.id);
+ return channel;
+}
+
+LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
+{
+ LLScreenChannel* new_channel = new LLScreenChannel(p.id);
if(!new_channel)
{
@@ -172,20 +182,26 @@ LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
{
new_channel->setToastAlignment(p.toast_align);
new_channel->setChannelAlignment(p.channel_align);
- new_channel->setDisplayToastsAlways(p.display_toasts_always);
-
- ChannelElem new_elem;
- new_elem.id = p.id;
- new_elem.channel = new_channel;
+ new_channel->setDisplayToastsAlways(p.display_toasts_always);
- mChannelList.push_back(new_elem);
+ addChannel(new_channel);
}
-
return new_channel;
}
+LLScreenChannelBase* LLChannelManager::getChannel(LLChannelManager::Params& p)
+{
+ LLScreenChannelBase* new_channel = findChannelByID(p.id);
+
+ if(new_channel)
+ return new_channel;
+
+ return createChannel(p);
+
+}
+
//--------------------------------------------------------------------------
-LLScreenChannel* LLChannelManager::findChannelByID(const LLUUID id)
+LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID id)
{
std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
if(it != mChannelList.end())
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index 811fa06d2b..b927d369cd 100644
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
@@ -52,8 +52,8 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
public:
struct Params
{
- LLUUID id;
- bool display_toasts_always;
+ LLUUID id;
+ bool display_toasts_always;
EToastAlignment toast_align;
EChannelAlignment channel_align;
@@ -64,7 +64,7 @@ public:
struct ChannelElem
{
LLUUID id;
- LLScreenChannel* channel;
+ LLScreenChannelBase* channel;
ChannelElem() : id(LLUUID("")), channel(NULL) { }
@@ -89,19 +89,23 @@ public:
void onStartUpToastClose();
// creates a new ScreenChannel according to the given parameters or returns existing if present
- LLScreenChannel* getChannel(LLChannelManager::Params& p);
+ LLScreenChannelBase* getChannel(LLChannelManager::Params& p);
+
+ LLScreenChannelBase* addChannel(LLScreenChannelBase* channel);
// returns a channel by its ID
- LLScreenChannel* findChannelByID(const LLUUID id);
+ LLScreenChannelBase* findChannelByID(const LLUUID id);
// creator of the Notification channel, that is used in more than one handler
- LLScreenChannel* createNotificationChannel();
+ LLScreenChannel* createNotificationChannel();
// remove channel methods
void removeChannelByID(const LLUUID id);
private:
+ LLScreenChannel* createChannel(LLChannelManager::Params& p);
+
LLScreenChannel* mStartUpChannel;
std::vector<ChannelElem> mChannelList;
};
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 96c707b08f..4523267edd 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -125,8 +125,8 @@ BOOL LLChatBar::postBuild()
mInputEditor = getChild<LLLineEditor>("Chat Editor");
mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke, this);
- mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this);
- mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this );
+ mInputEditor->setFocusLostCallback(boost::bind(&LLChatBar::onInputEditorFocusLost));
+ mInputEditor->setFocusReceivedCallback(boost::bind(&LLChatBar::onInputEditorGainFocus));
mInputEditor->setCommitOnFocusLost( FALSE );
mInputEditor->setRevertOnEsc( FALSE );
mInputEditor->setIgnoreTab(TRUE);
@@ -538,14 +538,14 @@ void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata )
}
// static
-void LLChatBar::onInputEditorFocusLost( LLFocusableElement* caller, void* userdata)
+void LLChatBar::onInputEditorFocusLost()
{
// stop typing animation
gAgent.stopTyping();
}
// static
-void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userdata )
+void LLChatBar::onInputEditorGainFocus()
{
LLFloaterChat::setHistoryCursorAndScrollToEnd();
}
diff --git a/indra/newview/llchatbar.h b/indra/newview/llchatbar.h
index a41947218d..86aa3ebd2a 100644
--- a/indra/newview/llchatbar.h
+++ b/indra/newview/llchatbar.h
@@ -87,8 +87,8 @@ public:
static void onTabClick( void* userdata );
static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
- static void onInputEditorFocusLost(LLFocusableElement* caller,void* userdata);
- static void onInputEditorGainFocus(LLFocusableElement* caller,void* userdata);
+ static void onInputEditorFocusLost();
+ static void onInputEditorGainFocus();
void onCommitGesture(LLUICtrl* ctrl);
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 6fb6552f2d..c2d7e0d935 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -44,6 +44,7 @@
#include "llviewercontrol.h"
#include "llagentdata.h"
+/*
static const S32 BORDER_MARGIN = 2;
static const S32 PARENT_BORDER_MARGIN = 0;
@@ -53,33 +54,27 @@ static const F32 MIN_AUTO_SCROLL_RATE = 120.f;
static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
-static const S32 msg_left_offset = 30;
-static const S32 msg_right_offset = 10;
-
#define MAX_CHAT_HISTORY 100
+*/
+static const S32 msg_left_offset = 30;
+static const S32 msg_right_offset = 10;
-static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container");
-
-
+//static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container");
//*******************************************************************************************************************
//LLChatItemCtrl
//*******************************************************************************************************************
-LLChatItemCtrl* LLChatItemCtrl::createInstance()
+LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance()
{
- LLChatItemCtrl* item = new LLChatItemCtrl();
+ LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel();
LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml");
+ item->setFollows(FOLLOWS_NONE);
return item;
}
-void LLChatItemCtrl::draw()
-{
- LLPanel::draw();
-}
-
-void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
+void LLNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_parent )
{
LLPanel::reshape(width, height,called_from_parent);
@@ -101,13 +96,13 @@ void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
}
}
-BOOL LLChatItemCtrl::postBuild()
+BOOL LLNearbyChatToastPanel::postBuild()
{
return LLPanel::postBuild();
}
-std::string LLChatItemCtrl::appendTime()
+std::string LLNearbyChatToastPanel::appendTime()
{
time_t utc_time;
utc_time = time_corrected();
@@ -124,48 +119,63 @@ std::string LLChatItemCtrl::appendTime()
-void LLChatItemCtrl::addText (const std::string& message)
+void LLNearbyChatToastPanel::addText (const std::string& message)
{
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
msg_text->addText(message);
mMessages.push_back(message);
}
-void LLChatItemCtrl::setMessage (const LLChat& msg)
+void LLNearbyChatToastPanel::init(LLSD& notification)
{
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
+ mText = notification["message"].asString(); // UTF-8 line of text
+ mFromName = notification["from"].asString(); // agent or object name
+ mFromID = notification["from_id"].asUUID(); // agent id or object id
+ int sType = notification["source"].asInteger();
+ mSourceType = (EChatSourceType)sType;
+
std::string str_sender;
-
- if(gAgentID != msg.mFromID)
- str_sender = msg.mFromName;
+ if(gAgentID != mFromID)
+ str_sender = mFromName;
else
str_sender = LLTrans::getString("You");;
caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender);
- std::string tt = appendTime();
-
- caption->getChild<LLTextBox>("msg_time", false)->setText(tt);
-
-
- caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(msg.mFromID);
+ caption->getChild<LLTextBox>("msg_time", false)->setText(appendTime());
- mOriginalMessage = msg;
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
- msg_text->setText(msg.mText);
+ msg_text->setText(mText);
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
- if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ if(mSourceType != CHAT_SOURCE_AGENT)
msg_inspector->setVisible(false);
mMessages.clear();
+ snapToMessageHeight ();
+
+ mIsDirty = true;//will set Avatar Icon in draw
+}
+
+void LLNearbyChatToastPanel::setMessage (const LLChat& chat_msg)
+{
+ LLSD notification;
+ notification["message"] = chat_msg.mText;
+ notification["from"] = chat_msg.mFromName;
+ notification["from_id"] = chat_msg.mFromID;
+ notification["time"] = chat_msg.mTime;
+ notification["source"] = (S32)chat_msg.mSourceType;
+
+ init(notification);
+
}
-void LLChatItemCtrl::snapToMessageHeight ()
+void LLNearbyChatToastPanel::snapToMessageHeight ()
{
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
S32 new_height = text_box->getTextPixelHeight();
@@ -184,14 +194,14 @@ void LLChatItemCtrl::snapToMessageHeight ()
}
-void LLChatItemCtrl::setWidth(S32 width)
+void LLNearbyChatToastPanel::setWidth(S32 width)
{
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/);
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
- if(mOriginalMessage.mText.length())
- msg_text->setText(mOriginalMessage.mText);
+ if(mText.length())
+ msg_text->setText(mText);
for(size_t i=0;i<mMessages.size();++i)
msg_text->addText(mMessages[i]);
@@ -200,25 +210,25 @@ void LLChatItemCtrl::setWidth(S32 width)
snapToMessageHeight ();
}
-void LLChatItemCtrl::onMouseLeave (S32 x, S32 y, MASK mask)
+void LLNearbyChatToastPanel::onMouseLeave (S32 x, S32 y, MASK mask)
{
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
msg_inspector->setVisible(false);
}
-void LLChatItemCtrl::onMouseEnter (S32 x, S32 y, MASK mask)
+void LLNearbyChatToastPanel::onMouseEnter (S32 x, S32 y, MASK mask)
{
- if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ if(mSourceType != CHAT_SOURCE_AGENT)
return;
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
msg_inspector->setVisible(true);
}
-BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
+BOOL LLNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask)
{
- if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ if(mSourceType != CHAT_SOURCE_AGENT)
return LLPanel::handleMouseDown(x,y,mask);
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
@@ -226,12 +236,16 @@ BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom;
if(msg_inspector->pointInView(local_x, local_y))
{
- LLFloaterReg::showInstance("inspect_avatar", mOriginalMessage.mFromID);
+ LLFloaterReg::showInstance("inspect_avatar", mFromID);
+ }
+ else
+ {
+ LLFloaterReg::showInstance("nearby_chat",LLSD());
}
return LLPanel::handleMouseDown(x,y,mask);
}
-void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
+void LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
{
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
@@ -243,7 +257,7 @@ void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
}
-bool LLChatItemCtrl::canAddText ()
+bool LLNearbyChatToastPanel::canAddText ()
{
LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
if(!msg_text)
@@ -251,7 +265,7 @@ bool LLChatItemCtrl::canAddText ()
return msg_text->getTextLinesNum()<10;
}
-BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+BOOL LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon", false);
@@ -260,296 +274,20 @@ BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom;
//eat message for avatar icon if msg was from object
- if(avatar_icon->pointInView(local_x, local_y) && mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT)
return TRUE;
return LLPanel::handleRightMouseDown(x,y,mask);
}
-
-
-//*******************************************************************************************************************
-//LLChatItemsContainerCtrl
-//*******************************************************************************************************************
-
-LLChatItemsContainerCtrl::LLChatItemsContainerCtrl(const Params& params):LLPanel(params)
-{
- mEShowItemHeader = CHATITEMHEADER_SHOW_BOTH;
-}
-
-
-void LLChatItemsContainerCtrl::addMessage(const LLChat& msg)
-{
- /*
- if(msg.mChatType == CHAT_TYPE_DEBUG_MSG)
- return;
- */
- if(mItems.size() >= MAX_CHAT_HISTORY)
- {
- LLChatItemCtrl* item = mItems[0];
- removeChild(item);
- delete item;
- mItems.erase(mItems.begin());
- }
-
-
- if(mItems.size() > 0
- && msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID
- && (msg.mTime-mItems[mItems.size()-1]->getMessage().mTime)<60
- && mItems[mItems.size()-1]->canAddText()
- )
- {
- mItems[mItems.size()-1]->addText(msg.mText);
- mItems[mItems.size()-1]->snapToMessageHeight();
- }
- else
- {
- LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
- mItems.push_back(item);
- addChild(item,0);
- item->setWidth(getRect().getWidth() - 16);
- item->setMessage(msg);
- item->snapToMessageHeight();
-
- item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
-
- item->setVisible(true);
- }
-
- arrange(getRect().getWidth(),getRect().getHeight());
- updateLayout(getRect().getWidth(),getRect().getHeight());
- scrollToBottom();
-}
-
-void LLChatItemsContainerCtrl::scrollToBottom ()
-{
- if(mScrollbar->getVisible())
- {
- mScrollbar->setDocPos(mScrollbar->getDocPosMax());
- onScrollPosChangeCallback(0,0);
- }
-}
-
-void LLChatItemsContainerCtrl::draw()
-{
- LLLocalClipRect clip(getRect());
- LLPanel::draw();
-}
-
-void LLChatItemsContainerCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
-{
- S32 delta_width = width - getRect().getWidth();
- S32 delta_height = height - getRect().getHeight();
-
- if (delta_width || delta_height || sForceReshape)
- {
- arrange(width, height);
- }
-
- updateBoundingRect();
-}
-
-void LLChatItemsContainerCtrl::arrange (S32 width, S32 height)
+void LLNearbyChatToastPanel::draw()
{
- S32 delta_width = width - getRect().getWidth();
- if(delta_width)//width changed...too bad. now we need to reformat all items
- reformatHistoryScrollItems(width);
-
- calcRecuiredHeight();
-
- show_hide_scrollbar(width,height);
-
- updateLayout(width,height);
-}
-
-void LLChatItemsContainerCtrl::reformatHistoryScrollItems(S32 width)
-{
- for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
- {
- (*it)->setWidth(width);
- }
-}
-
-S32 LLChatItemsContainerCtrl::calcRecuiredHeight ()
-{
- S32 rec_height = 0;
-
- std::vector<LLChatItemCtrl*>::iterator it;
- for(it=mItems.begin(); it!=mItems.end(); ++it)
- {
- rec_height += (*it)->getRect().getHeight();
- }
-
- mInnerRect.setLeftTopAndSize(0,rec_height + BORDER_MARGIN*2,getRect().getWidth(),rec_height + BORDER_MARGIN);
-
- return mInnerRect.getHeight();
-}
-
-
-void LLChatItemsContainerCtrl::updateLayout (S32 width, S32 height)
-{
- S32 panel_top = height - BORDER_MARGIN ;
- S32 panel_width = width;
- if(mScrollbar->getVisible())
- {
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
- panel_top+=mScrollbar->getDocPos();
- panel_width-=scrollbar_size;
- }
-
-
- //set sizes for first panels and dragbars
- for(size_t i=0;i<mItems.size();++i)
- {
- LLRect panel_rect = mItems[i]->getRect();
- panelSetLeftTopAndSize(mItems[i],panel_rect.mLeft,panel_top,panel_width,panel_rect.getHeight());
- panel_top-=panel_rect.getHeight();
- }
-}
-
-void LLChatItemsContainerCtrl::show_hide_scrollbar (S32 width, S32 height)
-{
- calcRecuiredHeight();
- if(getRecuiredHeight() > height )
- showScrollbar(width, height);
- else
- hideScrollbar(width, height);
-}
-
-void LLChatItemsContainerCtrl::showScrollbar (S32 width, S32 height)
-{
- bool was_visible = mScrollbar->getVisible();
-
- mScrollbar->setVisible(true);
-
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
- panelSetLeftTopAndSize(mScrollbar,width-scrollbar_size
- ,height-PARENT_BORDER_MARGIN,scrollbar_size,height-2*PARENT_BORDER_MARGIN);
-
- mScrollbar->setPageSize(height);
- mScrollbar->setDocParams(mInnerRect.getHeight(),mScrollbar->getDocPos());
-
- if(was_visible)
- {
- S32 scroll_pos = llmin(mScrollbar->getDocPos(), getRecuiredHeight() - height - 1);
- mScrollbar->setDocPos(scroll_pos);
- updateLayout(width,height);
- return;
- }
-}
-
-void LLChatItemsContainerCtrl::hideScrollbar (S32 width, S32 height)
-{
- if(mScrollbar->getVisible() == false)
- return;
- mScrollbar->setVisible(false);
-
- mScrollbar->setDocPos(0);
-
- if(mItems.size()>0)
- {
- S32 panel_top = height - BORDER_MARGIN; // Top coordinate of the first panel
- S32 diff = panel_top - mItems[0]->getRect().mTop;
- shiftPanels(diff);
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLChatItemsContainerCtrl::panelSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S32 width, S32 height)
-{
- if(!panel)
- return;
- LLRect panel_rect = panel->getRect();
- panel_rect.setLeftTopAndSize( left, top, width, height);
- panel->reshape( width, height, 1);
- panel->setRect(panel_rect);
-}
-
-void LLChatItemsContainerCtrl::panelShiftVertical(LLView* panel,S32 delta)
-{
- if(!panel)
- return;
- panel->translate(0,delta);
-}
-
-void LLChatItemsContainerCtrl::shiftPanels(S32 delta)
-{
- //Arrange panels
- for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
- {
- panelShiftVertical((*it),delta);
- }
-
-}
-
-//---------------------------------------------------------------------------------
-
-void LLChatItemsContainerCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
-{
- updateLayout(getRect().getWidth(),getRect().getHeight());
-}
-
-BOOL LLChatItemsContainerCtrl::postBuild()
-{
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
- LLRect scroll_rect;
- scroll_rect.setOriginAndSize(
- getRect().getWidth() - scrollbar_size,
- 1,
- scrollbar_size,
- getRect().getHeight() - 1);
-
-
- LLScrollbar::Params sbparams;
- sbparams.name("scrollable vertical");
- sbparams.rect(scroll_rect);
- sbparams.orientation(LLScrollbar::VERTICAL);
- sbparams.doc_size(mInnerRect.getHeight());
- sbparams.doc_pos(0);
- sbparams.page_size(mInnerRect.getHeight());
- sbparams.step_size(VERTICAL_MULTIPLE);
- sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
- sbparams.change_callback(boost::bind(&LLChatItemsContainerCtrl::onScrollPosChangeCallback, this, _1, _2));
-
- mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
- LLView::addChild( mScrollbar );
- mScrollbar->setVisible( true );
- mScrollbar->setFollowsRight();
- mScrollbar->setFollowsTop();
- mScrollbar->setFollowsBottom();
-
- reformatHistoryScrollItems(getRect().getWidth());
- arrange(getRect().getWidth(),getRect().getHeight());
-
- return LLPanel::postBuild();
-}
-BOOL LLChatItemsContainerCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
-{
- return LLPanel::handleMouseDown(x,y,mask);
-}
-BOOL LLChatItemsContainerCtrl::handleKeyHere (KEY key, MASK mask)
-{
- if( mScrollbar->getVisible() && mScrollbar->handleKeyHere( key,mask ) )
- return TRUE;
- return LLPanel::handleKeyHere(key,mask);
-}
-BOOL LLChatItemsContainerCtrl::handleScrollWheel ( S32 x, S32 y, S32 clicks )
-{
- if( mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) )
- return TRUE;
- return false;
-}
-
-void LLChatItemsContainerCtrl::setHeaderVisibility(EShowItemHeader e)
-{
- if(e == mEShowItemHeader)
- return;
- mEShowItemHeader = e;
- for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
+ if(mIsDirty)
{
- (*it)->setHeaderVisibility(e);
+ LLPanel* caption = findChild<LLPanel>("msg_caption", false);
+ if(caption)
+ caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(mFromID);
+ mIsDirty = false;
}
+ LLToastPanelBase::draw();
}
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index de16cf9505..8fb045b6d9 100644
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -37,6 +37,7 @@
#include "llscrollbar.h"
#include "string"
#include "llchat.h"
+#include "lltoastpanel.h"
typedef enum e_show_item_header
{
@@ -45,20 +46,18 @@ typedef enum e_show_item_header
CHATITEMHEADER_SHOW_BOTH
} EShowItemHeader;
-class LLChatItemCtrl: public LLPanel
+class LLNearbyChatToastPanel: public LLToastPanelBase
{
protected:
- LLChatItemCtrl(){};
+ LLNearbyChatToastPanel():mIsDirty(false){};
public:
- ~LLChatItemCtrl(){}
+ ~LLNearbyChatToastPanel(){}
- static LLChatItemCtrl* createInstance();
+ static LLNearbyChatToastPanel* createInstance();
- void draw();
-
- const LLChat& getMessage() const { return mOriginalMessage;}
+ const LLUUID& getFromID() const { return mFromID;}
void addText (const std::string& message);
void setMessage (const LLChat& msg);
@@ -77,78 +76,27 @@ public:
void setHeaderVisibility(EShowItemHeader e);
BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-private:
-
- std::string appendTime ();
-
-private:
- LLChat mOriginalMessage;
-
- std::vector<std::string> mMessages;
-};
-
-class LLChatItemsContainerCtrl: public LLPanel
-{
-public:
- struct Params
- : public LLInitParam::Block<Params, LLPanel::Params>
- {
- Params(){};
- };
-
- LLChatItemsContainerCtrl(const Params& params);
-
-
- ~LLChatItemsContainerCtrl(){}
-
- void addMessage (const LLChat& msg);
-
- void draw();
-
- void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
-
- void onScrollPosChangeCallback(S32, LLScrollbar*);
-
- virtual BOOL postBuild();
-
- BOOL handleMouseDown (S32 x, S32 y, MASK mask);
- BOOL handleKeyHere (KEY key, MASK mask);
- BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
-
- void scrollToBottom ();
-
- void setHeaderVisibility(EShowItemHeader e);
- EShowItemHeader getHeaderVisibility() const { return mEShowItemHeader;};
+ virtual void init(LLSD& data);
+ virtual void draw();
private:
- void reformatHistoryScrollItems(S32 width);
- void arrange (S32 width, S32 height);
-
- S32 calcRecuiredHeight ();
- S32 getRecuiredHeight () const { return mInnerRect.getHeight(); }
-
- void updateLayout (S32 width, S32 height);
-
- void show_hide_scrollbar (S32 width, S32 height);
-
- void showScrollbar (S32 width, S32 height);
- void hideScrollbar (S32 width, S32 height);
-
- void panelSetLeftTopAndSize (LLView* panel, S32 left, S32 top, S32 width, S32 height);
- void panelShiftVertical (LLView* panel,S32 delta);
- void shiftPanels (S32 delta);
+
+ std::string appendTime ();
private:
- std::vector<LLChatItemCtrl*> mItems;
+ std::string mText; // UTF-8 line of text
+ std::string mFromName; // agent or object name
+ LLUUID mFromID; // agent id or object id
+ EChatSourceType mSourceType;
- EShowItemHeader mEShowItemHeader;
- LLRect mInnerRect;
- LLScrollbar* mScrollbar;
+ std::vector<std::string> mMessages;
+ bool mIsDirty;
};
+
#endif
diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp
index e6398dd47a..bd0c36b44a 100644
--- a/indra/newview/llchatmsgbox.cpp
+++ b/indra/newview/llchatmsgbox.cpp
@@ -102,7 +102,7 @@ void LLChatMsgBox::drawText(S32 x, S32 y, const LLWString &text, const LLColor4
// iterate through each block of text that has been added
y -= mLineSpacing;
- for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); true ;)
+ for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); it != mSeparatorOffset.end() ;)
{
// display the text for this block
S32 num_chars = *it - start;
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 20c44d5b11..98e492cada 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -49,6 +49,7 @@
#include "llvoicecontrolpanel.h"
#include "llgroupmgr.h"
#include "llnotificationmanager.h"
+#include "lltransientfloatermgr.h"
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
@@ -243,26 +244,36 @@ void LLIMChiclet::draw()
LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
{
EType type = TYPE_UNKNOWN;
- LLFloaterIMPanel* im = NULL;
if(session_id.isNull())
return type;
- if (!(im = LLIMMgr::getInstance()->findFloaterBySession(session_id)))
+ EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id);
+ if (IM_COUNT == im_type)
{
llassert_always(0 && "IM session not found"); // should never happen
return type;
}
- switch(im->getDialogType())
+ switch(im_type)
{
case IM_NOTHING_SPECIAL:
+ case IM_SESSION_P2P_INVITE:
type = TYPE_IM;
break;
case IM_SESSION_GROUP_START:
case IM_SESSION_INVITE:
- type = TYPE_GROUP;
+ if (gAgent.isInGroup(session_id))
+ {
+ type = TYPE_GROUP;
+ }
+ else
+ {
+ type = TYPE_AD_HOC;
+ }
break;
+ case IM_SESSION_CONFERENCE_START:
+ type = TYPE_AD_HOC;
default:
break;
}
@@ -285,6 +296,11 @@ LLIMP2PChiclet::Params::Params()
avatar_icon.name("avatar_icon");
avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
+
+ // *NOTE dzaporozhan
+ // Changed icon height from 25 to 24 to fix ticket EXT-794.
+ // In some cases(after changing UI scale) 25 pixel height icon was
+ // drawn incorrectly, i'm not sure why.
avatar_icon.rect(LLRect(0, 24, 25, 0));
avatar_icon.mouse_opaque(false);
@@ -458,6 +474,11 @@ LLIMGroupChiclet::Params::Params()
rect(LLRect(0, 25, 45, 0));
group_icon.name("group_icon");
+
+ // *NOTE dzaporozhan
+ // Changed icon height from 25 to 24 to fix ticket EXT-794.
+ // In some cases(after changing UI scale) 25 pixel height icon was
+ // drawn incorrectly, i'm not sure why.
group_icon.rect(LLRect(0, 24, 25, 0));
unread_notifications.name("unread");
@@ -1164,6 +1185,7 @@ LLTalkButton::LLTalkButton(const Params& p)
speak_params.rect(speak_rect);
mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
addChild(mSpeakBtn);
+ LLTransientFloaterMgr::getInstance()->addControlView(mSpeakBtn);
mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this));
mSpeakBtn->setToggleState(FALSE);
@@ -1172,6 +1194,7 @@ LLTalkButton::LLTalkButton(const Params& p)
show_params.rect(show_rect);
mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
addChild(mShowBtn);
+ LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn);
mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this));
mShowBtn->setToggleState(FALSE);
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 316348cf1d..ef47b54333 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -275,7 +275,8 @@ public:
enum EType {
TYPE_UNKNOWN,
TYPE_IM,
- TYPE_GROUP
+ TYPE_GROUP,
+ TYPE_AD_HOC
};
/*virtual*/ ~LLIMChiclet() {};
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index 9957694727..979a1a9a60 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -125,7 +125,7 @@ LLCurrencyUIManager::Impl::Impl(LLPanel& dialog)
mUserCurrencyBuy(2000), // note, this is a default, real value set in llfloaterbuycurrency.cpp
mUserEnteredCurrencyBuy(false),
mSiteCurrencyEstimated(false),
- mSiteCurrencyEstimatedCost(0),
+ mSiteCurrencyEstimatedCost(0),
mBought(false),
mTransactionType(TransactionNone), mTransaction(0),
mCurrencyChanged(false)
@@ -394,7 +394,7 @@ void LLCurrencyUIManager::Impl::updateUI()
}
}
- mPanel.childSetTextArg("currency_est", "[USD]", llformat("%#.2f", mSiteCurrencyEstimatedCost / 100.0));
+ mPanel.childSetTextArg("currency_est", "[LOCALAMOUNT]", "US$ " + llformat("%#.2f", mSiteCurrencyEstimatedCost / 100.0));
mPanel.childSetVisible("currency_est", mSiteCurrencyEstimated && mUserCurrencyBuy > 0);
if (mPanel.childIsEnabled("buy_btn")
@@ -478,7 +478,7 @@ void LLCurrencyUIManager::buy(const std::string& buy_msg)
LLUIString msg = buy_msg;
msg.setArg("[LINDENS]", llformat("%d", impl.mUserCurrencyBuy));
- msg.setArg("[USD]", llformat("%#.2f", impl.mSiteCurrencyEstimatedCost / 100.0));
+ msg.setArg("[LOCALAMOUNT]", "US$ " + llformat("%#.2f", impl.mSiteCurrencyEstimatedCost / 100.0));
LLConfirmationManager::confirm(impl.mSiteConfirm,
msg,
impl,
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 4cf12a1533..069155c255 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -960,6 +960,30 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
return retval;
}
+const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
+//static
+S32 LLDrawable::getMinVisFrameRange()
+{
+ return MIN_VIS_FRAME_RANGE ;
+}
+
+BOOL LLDrawable::isRecentlyVisible() const
+{
+ //currently visible or visible in the previous frame.
+ BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ;
+
+ if(!vis)
+ {
+ LLSpatialGroup* group = getSpatialGroup();
+ if (group && group->isRecentlyVisible())
+ {
+ mVisible = sCurVisible;
+ vis = TRUE ;
+ }
+ }
+
+ return vis ;
+}
BOOL LLDrawable::isVisible() const
{
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 986440397b..5a10b688da 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -78,7 +78,8 @@ public:
BOOL isLight() const;
- BOOL isVisible() const;
+ BOOL isVisible() const;
+ BOOL isRecentlyVisible() const;
virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
@@ -278,7 +279,8 @@ public:
S32 mQuietCount;
static S32 getCurrentFrame() { return sCurVisible; }
-
+ static S32 getMinVisFrameRange();
+
void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index fc5b27dd1b..a5b0b05603 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -270,16 +270,34 @@ void LLFace::setTexture(LLViewerTexture* tex)
{
mTexture->removeFace(this) ;
removeAtlas() ;
- }
+ }
mTexture = tex ;
-
+
if(mTexture.notNull())
{
mTexture->addFace(this) ;
}
}
+void LLFace::switchTexture(LLViewerTexture* new_texture)
+{
+ if(mTexture == new_texture)
+ {
+ return ;
+ }
+
+ if(!new_texture)
+ {
+ llerrs << "Can not switch to a null texture." << llendl ;
+ }
+ new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
+
+ getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
+ setTexture(new_texture) ;
+ gPipeline.markTextured(getDrawable());
+}
+
void LLFace::setTEOffset(const S32 te_offset)
{
mTEOffset = te_offset;
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index cafad5706c..f6ffefcb7c 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -89,6 +89,7 @@ public:
U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
void setTexture(LLViewerTexture* tex) ;
+ void switchTexture(LLViewerTexture* new_texture);
LLXformMatrix* getXform() const { return mXform; }
BOOL hasGeometry() const { return mGeomCount > 0; }
LLVector3 getPositionAgent() const;
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 6b18984f88..ea947a5565 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -934,6 +934,17 @@ void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S
LLMenuGL::showPopup(fav_button, menu, x, y);
}
+BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = childrenHandleRightMouseDown( x, y, mask) != NULL;
+ if(!handled && !gMenuHolder->hasVisibleMenu())
+ {
+ show_navbar_context_menu(this,x,y);
+ handled = true;
+ }
+
+ return handled;
+}
void copy_slurl_to_clipboard_cb(std::string& slurl)
{
gClipboard.copyFromString(utf8str_to_wstring(slurl));
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 0be8de29a9..97117c3b4a 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -62,7 +62,7 @@ public:
std::string& tooltip_msg);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
-
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
// LLInventoryObserver observer trigger
virtual void changed(U32 mask);
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index 0107cb6fe2..5c4b8552a6 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -159,6 +159,9 @@ void LLFloaterBuyCurrencyUI::draw()
updateUI();
}
+ // disable the Buy button when we are not able to buy
+ childSetEnabled("buy_btn", mManager.canBuy());
+
LLFloater::draw();
}
@@ -194,29 +197,19 @@ void LLFloaterBuyCurrencyUI::updateUI()
// error section
if (hasError)
{
- mChildren.setBadge(std::string("step_error"), LLViewChildren::BADGE_ERROR);
-
- LLTextBox* message = getChild<LLTextBox>("error_message");
- if (message)
- {
- message->setVisible(true);
- message->setWrappedText(mManager.errorMessage());
- }
-
- childSetVisible("error_web", !mManager.errorURI().empty());
- if (!mManager.errorURI().empty())
- {
- childHide("getting_data");
- }
+ childHide("normal_background");
+ childShow("error_background");
+ childShow("cannot_buy_message");
+ childShow("error_web");
}
else
{
- childHide("step_error");
- childHide("error_message");
+ childShow("normal_background");
+ childHide("error_background");
+ childHide("cannot_buy_message");
childHide("error_web");
}
-
-
+
// currency
childSetVisible("contacting", false);
childSetVisible("buy_action", false);
@@ -224,8 +217,6 @@ void LLFloaterBuyCurrencyUI::updateUI()
if (!hasError)
{
- mChildren.setBadge(std::string("step_1"), LLViewChildren::BADGE_NOTE);
-
if (mManager.buying())
{
childSetVisible("contacting", true);
@@ -286,9 +277,8 @@ void LLFloaterBuyCurrencyUI::updateUI()
childHide("purchase_warning_notenough");
}
- childSetEnabled("buy_btn", mManager.canBuy());
-
- if (!mManager.canBuy() && !childIsVisible("error_web"))
+ childHide("getting_data");
+ if (!mManager.canBuy() && !hasError)
{
childShow("getting_data");
}
@@ -298,10 +288,6 @@ void LLFloaterBuyCurrencyUI::onClickBuy()
{
mManager.buy(getString("buy_currency"));
updateUI();
- // JC: updateUI() doesn't get called again until progress is made
- // with transaction processing, so the "Purchase" button would be
- // left enabled for some time. Pre-emptively disable.
- childSetEnabled("buy_btn", false);
}
void LLFloaterBuyCurrencyUI::onClickCancel()
@@ -311,7 +297,7 @@ void LLFloaterBuyCurrencyUI::onClickCancel()
void LLFloaterBuyCurrencyUI::onClickErrorWeb()
{
- LLWeb::loadURLExternal(mManager.errorURI());
+ LLWeb::loadURLExternal(getString("account_website"));
closeFloater();
}
diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 14fb93df61..ca43f41d05 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -66,7 +66,6 @@
#include "lllogchat.h"
#include "lltexteditor.h"
#include "lltextparser.h"
-#include "llfloaterhtml.h"
#include "llweb.h"
#include "llstylemap.h"
diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp
index 05ea800d0e..dea656b0e4 100644
--- a/indra/newview/llfloaterchatterbox.cpp
+++ b/indra/newview/llfloaterchatterbox.cpp
@@ -363,7 +363,8 @@ LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
{
// only LLFloaterIMPanels are called "im_floater"
LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp;
- if (im_floaterp->getVoiceChannel() == LLVoiceChannel::getCurrentVoiceChannel())
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(im_floaterp->getSessionID());
+ if (voice_channel == LLVoiceChannel::getCurrentVoiceChannel())
{
return im_floaterp;
}
diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp
new file mode 100644
index 0000000000..6b0b5ed5e0
--- /dev/null
+++ b/indra/newview/llfloaterhelpbrowser.cpp
@@ -0,0 +1,142 @@
+/**
+ * @file llfloaterhelpbrowser.cpp
+ * @brief HTML Help floater - uses embedded web browser control
+ *
+ * $LicenseInfo:firstyear=2006&license=viewergpl$
+ *
+ * Copyright (c) 2006-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterhelpbrowser.h"
+
+#include "llfloaterreg.h"
+#include "llpluginclassmedia.h"
+#include "llmediactrl.h"
+#include "llviewerwindow.h"
+#include "llviewercontrol.h"
+#include "llweb.h"
+#include "llui.h"
+
+#include "llurlhistory.h"
+#include "llmediactrl.h"
+#include "llviewermedia.h"
+
+
+LLFloaterHelpBrowser::LLFloaterHelpBrowser(const LLSD& key)
+ : LLFloater(key)
+{
+ // really really destroy the help browser when it's closed, it'll be recreated.
+ // *TODO: when onClose() is resurrected as a virtual, this bind can go away.
+ mCloseSignal.connect(boost::bind(&LLFloaterHelpBrowser::onClose, this));
+}
+
+BOOL LLFloaterHelpBrowser::postBuild()
+{
+ mBrowser = getChild<LLMediaCtrl>("browser");
+ mBrowser->addObserver(this);
+
+ childSetAction("open_browser", onClickOpenWebBrowser, this);
+
+ buildURLHistory();
+ return TRUE;
+}
+
+void LLFloaterHelpBrowser::buildURLHistory()
+{
+ // Get all of the entries in the "browser" collection
+ LLSD browser_history = LLURLHistory::getURLHistory("browser");
+
+ // initialize URL history in the plugin
+ LLPluginClassMedia *plugin = mBrowser->getMediaPlugin();
+ if (plugin)
+ {
+ plugin->initializeUrlHistory(browser_history);
+ }
+}
+
+void LLFloaterHelpBrowser::onClose()
+{
+ destroy(); // really destroy this dialog on closure, it's relatively heavyweight.
+}
+
+void LLFloaterHelpBrowser::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ if(event == MEDIA_EVENT_LOCATION_CHANGED)
+ {
+ setCurrentURL(self->getLocation());
+ }
+ else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
+ {
+ // nothing yet
+ }
+}
+
+void LLFloaterHelpBrowser::setCurrentURL(const std::string& url)
+{
+ mCurrentURL = url;
+
+ // redirects will navigate momentarily to about:blank, don't add to history
+ if (mCurrentURL != "about:blank")
+ {
+ // Serialize url history
+ LLURLHistory::removeURL("browser", mCurrentURL);
+ LLURLHistory::addURL("browser", mCurrentURL);
+ }
+}
+
+//static
+void LLFloaterHelpBrowser::onClickClose(void* user_data)
+{
+ LLFloaterHelpBrowser* self = (LLFloaterHelpBrowser*)user_data;
+
+ self->closeFloater();
+}
+
+//static
+void LLFloaterHelpBrowser::onClickOpenWebBrowser(void* user_data)
+{
+ LLFloaterHelpBrowser* self = (LLFloaterHelpBrowser*)user_data;
+
+ std::string url = self->mCurrentURL.empty() ?
+ self->mBrowser->getHomePageUrl() :
+ self->mCurrentURL;
+ LLWeb::loadURLExternal(url);
+}
+
+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);
+ setCurrentURL(media_url);
+}
+
+void LLFloaterHelpBrowser::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )
+{
+ mBrowser->navigateToLocalPage(subdir, filename_in);
+}
diff --git a/indra/newview/llfloaterhelpbrowser.h b/indra/newview/llfloaterhelpbrowser.h
new file mode 100644
index 0000000000..14a276b428
--- /dev/null
+++ b/indra/newview/llfloaterhelpbrowser.h
@@ -0,0 +1,72 @@
+/**
+ * @file llfloatermediabrowser.h
+ * @brief HTML Help floater - uses embedded web browser control
+ *
+ * $LicenseInfo:firstyear=2006&license=viewergpl$
+ *
+ * Copyright (c) 2006-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERHELPBROWSER_H
+#define LL_LLFLOATERHELPBROWSER_H
+
+#include "llfloater.h"
+#include "llmediactrl.h"
+
+
+class LLMediaCtrl;
+
+class LLFloaterHelpBrowser :
+ public LLFloater,
+ public LLViewerMediaObserver
+{
+ public:
+ LLFloaterHelpBrowser(const LLSD& key);
+
+ /*virtual*/ BOOL postBuild();
+ void onClose();
+
+ // inherited from LLViewerMediaObserver
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+
+ void openMedia(const std::string& media_url);
+
+ void navigateToLocalPage( const std::string& subdir, const std::string& filename_in );
+
+ private:
+ void buildURLHistory();
+ void setCurrentURL(const std::string& url);
+
+ static void onClickClose(void* user_data);
+ static void onClickOpenWebBrowser(void* user_data);
+
+ private:
+ LLMediaCtrl* mBrowser;
+ std::string mCurrentURL;
+};
+
+#endif // LL_LLFLOATERHELPBROWSER_H
+
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
index 27eb12b9cc..116286329c 100644
--- a/indra/newview/llfloaterinventory.cpp
+++ b/indra/newview/llfloaterinventory.cpp
@@ -1169,7 +1169,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p)
mScroller(NULL),
mSortOrderSetting(p.sort_order_setting),
mInventory(p.inventory),
- mAllowMultiSelect(p.allow_multi_select)
+ mAllowMultiSelect(p.allow_multi_select),
+ mHasInventoryConnection(false)
{
// contex menu callbacks
mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2));
@@ -1230,9 +1231,10 @@ BOOL LLInventoryPanel::postBuild()
mInventoryObserver = new LLInventoryPanelObserver(this);
mInventory->addObserver(mInventoryObserver);
// build view of inventory if inventory ready, otherwise wait for modelChanged() callback
- if (mInventory->isInventoryUsable())
+ if (mInventory->isInventoryUsable() && !mHasInventoryConnection)
{
rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD);
+ mHasInventoryConnection = true;
}
// bit of a hack to make sure the inventory is open.
@@ -1332,9 +1334,10 @@ void LLInventoryPanel::modelChanged(U32 mask)
bool handled = false;
// inventory just initialized, do complete build
- if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty())
+ if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection)
{
rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD);
+ mHasInventoryConnection = true;
return;
}
diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h
index a40efe020b..1aaac74c87 100644
--- a/indra/newview/llfloaterinventory.h
+++ b/indra/newview/llfloaterinventory.h
@@ -179,6 +179,7 @@ protected:
LLScrollContainer* mScroller;
BOOL mAllowMultiSelect;
std::string mSortOrderSetting;
+ bool mHasInventoryConnection;
};
class LLFloaterInventory;
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index e5f5e8eedb..3fe7d8d9da 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1043,7 +1043,7 @@ BOOL LLPanelLandObjects::postBuild()
mSelectedObjects = getChild<LLTextBox>("selected_objects_text");
mCleanOtherObjectsTime = getChild<LLLineEditor>("clean other time");
- mCleanOtherObjectsTime->setFocusLostCallback(onLostFocus, this);
+ mCleanOtherObjectsTime->setFocusLostCallback(boost::bind(onLostFocus, _1, this));
mCleanOtherObjectsTime->setCommitCallback(onCommitClean, this);
childSetPrevalidate("clean other time", LLLineEditor::prevalidateNonNegativeS32);
diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp
index c580cdef8a..9b7f3305e5 100644
--- a/indra/newview/llfloatermediabrowser.cpp
+++ b/indra/newview/llfloatermediabrowser.cpp
@@ -1,6 +1,6 @@
/**
- * @file llfloaterhtmlhelp.cpp
- * @brief HTML Help floater - uses embedded web browser control
+ * @file llfloatermediabrowser.cpp
+ * @brief media browser floater - uses embedded media browser control
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
@@ -33,7 +33,6 @@
#include "llviewerprecompiledheaders.h"
#include "llfloatermediabrowser.h"
-#include "llfloaterhtml.h"
#include "llfloaterreg.h"
#include "llparcel.h"
@@ -147,7 +146,10 @@ void LLFloaterMediaBrowser::buildURLHistory()
}
// initialize URL history in the plugin
- mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history);
+ if(mBrowser && mBrowser->getMediaPlugin())
+ {
+ mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history);
+ }
}
std::string LLFloaterMediaBrowser::getSupportURL()
@@ -330,69 +332,3 @@ void LLFloaterMediaBrowser::openMedia(const std::string& media_url)
mBrowser->navigateTo(media_url);
setCurrentURL(media_url);
}
-////////////////////////////////////////////////////////////////////////////////
-//
-
-LLViewerHtmlHelp gViewerHtmlHelp;
-
-
-////////////////////////////////////////////////////////////////////////////////
-//
-LLViewerHtmlHelp::LLViewerHtmlHelp()
-{
-
- LLUI::setHtmlHelp(this);
-}
-
-LLViewerHtmlHelp::~LLViewerHtmlHelp()
-{
-
- LLUI::setHtmlHelp(NULL);
-}
-
-void LLViewerHtmlHelp::show()
-{
- show("");
-}
-
-void LLViewerHtmlHelp::show(std::string url)
-{
- LLFloaterMediaBrowser* floater_html = dynamic_cast<LLFloaterMediaBrowser*>(LLFloaterReg::getInstance("media_browser"));
- floater_html->setVisible(FALSE);
-
- if (url.empty())
- {
- url = floater_html->getSupportURL();
- }
-
- if (gSavedSettings.getBOOL("UseExternalBrowser"))
- {
- LLSD notificationData;
- notificationData["url"] = url;
-
- LLNotifications::instance().add("ClickOpenF1Help", notificationData, LLSD(), onClickF1HelpLoadURL);
- floater_html->closeFloater();
- }
- else
- {
- // don't wait, just do it
- floater_html->setVisible(TRUE);
- floater_html->openMedia(url);
- }
-}
-
-// static
-bool LLViewerHtmlHelp::onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response)
-{
- LLFloaterMediaBrowser* floater_html = dynamic_cast<LLFloaterMediaBrowser*>(LLFloaterReg::getInstance("media_browser"));
- floater_html->setVisible(FALSE);
- std::string url = floater_html->getSupportURL();
- S32 option = LLNotification::getSelectedOption(notification, response);
- if (option == 0)
- {
- LLWeb::loadURL(url);
- }
- floater_html->closeFloater();
- return false;
-}
-
diff --git a/indra/newview/llfloatermediabrowser.h b/indra/newview/llfloatermediabrowser.h
index 76e8b517a0..c315f9e797 100644
--- a/indra/newview/llfloatermediabrowser.h
+++ b/indra/newview/llfloatermediabrowser.h
@@ -1,6 +1,6 @@
/**
* @file llfloatermediabrowser.h
- * @brief HTML Help floater - uses embedded web browser control
+ * @brief media browser floater - uses embedded media browser control
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
@@ -33,23 +33,9 @@
#ifndef LL_LLFLOATERMEDIABROWSER_H
#define LL_LLFLOATERMEDIABROWSER_H
-#include "llhtmlhelp.h"
#include "llfloater.h"
#include "llmediactrl.h"
-class LLViewerHtmlHelp : public LLHtmlHelp
-{
-public:
- LLViewerHtmlHelp();
- virtual ~LLViewerHtmlHelp();
-
- /*virtual*/ void show();
- /*virtual*/ void show(std::string start_url);
- void show(std::string start_url, std::string title);
-
- static bool onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response);
-
-};
class LLComboBox;
class LLMediaCtrl;
@@ -93,7 +79,5 @@ private:
std::string mCurrentURL;
};
-extern LLViewerHtmlHelp gViewerHtmlHelp;
-
#endif // LL_LLFLOATERMEDIABROWSER_H
diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
new file mode 100644
index 0000000000..811cc26efb
--- /dev/null
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -0,0 +1,249 @@
+/**
+ * @file llfloatermediasettings.cpp
+ * @brief Tabbed dialog for media settings - class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterreg.h"
+#include "llfloatermediasettings.h"
+#include "llpanelmediasettingsgeneral.h"
+#include "llpanelmediasettingssecurity.h"
+#include "llpanelmediasettingspermissions.h"
+#include "llviewercontrol.h"
+#include "lluictrlfactory.h"
+#include "llbutton.h"
+#include "llselectmgr.h"
+
+LLFloaterMediaSettings* LLFloaterMediaSettings::sInstance = NULL;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterMediaSettings::LLFloaterMediaSettings(const LLSD& key)
+ : LLFloater(key),
+ mTabContainer(NULL),
+ mPanelMediaSettingsGeneral(NULL),
+ mPanelMediaSettingsSecurity(NULL),
+ mPanelMediaSettingsPermissions(NULL),
+ mWaitingToClose( false )
+{
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_settings.xml");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterMediaSettings::~LLFloaterMediaSettings()
+{
+ if ( mPanelMediaSettingsGeneral )
+ {
+ delete mPanelMediaSettingsGeneral;
+ mPanelMediaSettingsGeneral = NULL;
+ }
+
+ if ( mPanelMediaSettingsSecurity )
+ {
+ delete mPanelMediaSettingsSecurity;
+ mPanelMediaSettingsSecurity = NULL;
+ }
+
+ if ( mPanelMediaSettingsPermissions )
+ {
+ delete mPanelMediaSettingsPermissions;
+ mPanelMediaSettingsPermissions = NULL;
+ }
+
+ sInstance = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLFloaterMediaSettings::postBuild()
+{
+ mCloseSignal.connect(boost::bind(&LLFloaterMediaSettings::onClose, this));
+
+ mApplyBtn = getChild<LLButton>("Apply");
+ mApplyBtn->setClickedCallback(onBtnApply, this);
+
+ mCancelBtn = getChild<LLButton>("Cancel");
+ mCancelBtn->setClickedCallback(onBtnCancel, this);
+
+ mOKBtn = getChild<LLButton>("OK");
+ mOKBtn->setClickedCallback(onBtnOK, this);
+
+ mTabContainer = getChild<LLTabContainer>( "tab_container" );
+
+ mPanelMediaSettingsGeneral = new LLPanelMediaSettingsGeneral();
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(mPanelMediaSettingsGeneral));
+ mPanelMediaSettingsGeneral->setParent( this );
+
+ // note that "permissions" tab is really "Controls" tab - refs to 'perms' and
+ // 'permissions' not changed to 'controls' since we don't want to change
+ // shared files in server code and keeping everything the same seemed best.
+ mPanelMediaSettingsPermissions = new LLPanelMediaSettingsPermissions();
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(mPanelMediaSettingsPermissions));
+
+ mPanelMediaSettingsSecurity = new LLPanelMediaSettingsSecurity();
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(mPanelMediaSettingsSecurity));
+
+ // restore the last tab viewed from persistance variable storage
+ if (!mTabContainer->selectTab(gSavedSettings.getS32("LastMediaSettingsTab")))
+ {
+ mTabContainer->selectFirstTab();
+ };
+
+ sInstance = this;
+
+ return TRUE;
+}
+
+//static
+LLFloaterMediaSettings* LLFloaterMediaSettings::getInstance()
+{
+ if ( !sInstance )
+ {
+ sInstance = (LLFloaterReg::getTypedInstance<LLFloaterMediaSettings>("media_settings"));
+ }
+
+ return sInstance;
+}
+
+//static
+void LLFloaterMediaSettings::apply()
+{
+
+ LLSD settings;
+ sInstance->mPanelMediaSettingsGeneral->getValues( settings );
+ sInstance->mPanelMediaSettingsSecurity->getValues( settings );
+ sInstance->mPanelMediaSettingsPermissions->getValues( settings );
+ LLSelectMgr::getInstance()->selectionSetMedia( LLTextureEntry::MF_HAS_MEDIA );
+ LLSelectMgr::getInstance()->selectionSetMediaData(settings);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void LLFloaterMediaSettings::onClose()
+{
+ if(mPanelMediaSettingsGeneral)
+ {
+ mPanelMediaSettingsGeneral->onClose();
+ }
+ LLFloaterReg::hideInstance("whitelist_entry");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//static
+void LLFloaterMediaSettings::initValues( const LLSD& media_settings )
+{
+ sInstance->clearValues();
+ // update all panels with values from simulator
+ sInstance->mPanelMediaSettingsGeneral->
+ initValues( sInstance->mPanelMediaSettingsGeneral, media_settings );
+
+ sInstance->mPanelMediaSettingsSecurity->
+ initValues( sInstance->mPanelMediaSettingsSecurity, media_settings );
+
+ sInstance->mPanelMediaSettingsPermissions->
+ initValues( sInstance->mPanelMediaSettingsPermissions, media_settings );
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFloaterMediaSettings::commitFields()
+{
+ if (hasFocus())
+ {
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus->acceptsTextInput())
+ {
+ cur_focus->onCommit();
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//static
+void LLFloaterMediaSettings::clearValues()
+{
+ // clean up all panels before updating
+ sInstance->mPanelMediaSettingsGeneral->clearValues(sInstance->mPanelMediaSettingsGeneral);
+ sInstance->mPanelMediaSettingsSecurity->clearValues(sInstance->mPanelMediaSettingsSecurity);
+ sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onBtnOK( void* userdata )
+{
+ sInstance->commitFields();
+
+ sInstance->apply();
+
+ sInstance->closeFloater();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onBtnApply( void* userdata )
+{
+ sInstance->commitFields();
+
+ sInstance->apply();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onBtnCancel( void* userdata )
+{
+ sInstance->closeFloater();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onTabChanged(void* user_data, bool from_click)
+{
+ LLTabContainer* self = (LLTabContainer*)user_data;
+ gSavedSettings.setS32("LastMediaSettingsTab", self->getCurrentPanelIndex());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFloaterMediaSettings::enableOkApplyBtns( bool enable )
+{
+ setCtrlsEnabled( enable );
+ childSetEnabled( "OK", enable );
+ childSetEnabled( "Apply", enable );
+}
diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h
new file mode 100644
index 0000000000..b95c590346
--- /dev/null
+++ b/indra/newview/llfloatermediasettings.h
@@ -0,0 +1,81 @@
+/**
+ * @file llfloatermediasettings.cpp
+ * @brief Tabbed dialog for media settings - class definition
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERMEDIASETTINGS_H
+#define LL_LLFLOATERMEDIASETTINGS_H
+
+#include "llfloater.h"
+#include "lltabcontainer.h"
+
+class LLPanelMediaSettingsGeneral;
+class LLPanelMediaSettingsSecurity;
+class LLPanelMediaSettingsPermissions;
+
+class LLFloaterMediaSettings :
+ public LLFloater
+{
+public:
+ LLFloaterMediaSettings(const LLSD& key);
+ ~LLFloaterMediaSettings();
+
+ virtual BOOL postBuild();
+ static LLFloaterMediaSettings* getInstance();
+ static void apply();
+ static void initValues( const LLSD& media_settings );
+ static void clearValues();
+ void enableOkApplyBtns( bool enable );
+ LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;};
+
+protected:
+ LLButton *mOKBtn;
+ LLButton *mCancelBtn;
+ LLButton *mApplyBtn;
+
+ LLTabContainer *mTabContainer;
+ LLPanelMediaSettingsGeneral* mPanelMediaSettingsGeneral;
+ LLPanelMediaSettingsSecurity* mPanelMediaSettingsSecurity;
+ LLPanelMediaSettingsPermissions* mPanelMediaSettingsPermissions;
+
+ void onClose();
+ static void onBtnOK(void*);
+ static void onBtnCancel(void*);
+ static void onBtnApply(void*);
+ static void onTabChanged(void* user_data, bool from_click);
+ void commitFields();
+
+ static LLFloaterMediaSettings* sInstance;
+
+private:
+ bool mWaitingToClose;
+};
+
+#endif // LL_LLFLOATERMEDIASETTINGS_H
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index fbc0ff3cf5..938370b732 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -106,7 +106,7 @@ BOOL LLFloaterPostcard::postBuild()
childSetValue("name_form", LLSD(name_string));
// For the first time a user focusess to .the msg box, all text will be selected.
- getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(onMsgFormFocusRecieved, this);
+ getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(boost::bind(onMsgFormFocusRecieved, _1, this));
childSetFocus("to_form", TRUE);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 761b5c9219..57c043a1e0 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -195,8 +195,8 @@ void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator);
viewer_media_t get_web_media()
{
- viewer_media_t media_source = LLViewerMedia::newMediaImpl("", LLUUID::null, 0, 0, 0, 0, "text/html");
-
+ viewer_media_t media_source = LLViewerMedia::newMediaImpl(LLUUID::null);
+ media_source->initializeMedia("text/html");
return media_source;
}
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 4d154c4cd3..3dcdc2f56e 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -1,6 +1,6 @@
/**
* @file llfloaterreporter.cpp
- * @brief Bug and abuse reports.
+ * @brief Abuse reports.
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
@@ -220,8 +220,7 @@ LLFloaterReporter::~LLFloaterReporter()
void LLFloaterReporter::draw()
{
// this is set by a static callback sometime after the dialog is created.
- // Only disable screenshot for abuse reports to estate owners - bug reports always
- // allow screenshots to be taken.
+ // Only disable screenshot for abuse reports to estate owners
if ( mEmailToEstateOwner )
{
childSetValue("screen_check", FALSE );
@@ -479,15 +478,6 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
if (f)
{
f->setReportType(report_type);
-
- if (report_type == BUG_REPORT)
- {
- LLNotifications::instance().add("HelpReportBug");
- }
- else
- {
- // popup for abuse reports is triggered elsewhere
- }
}
}
@@ -528,14 +518,7 @@ bool LLFloaterReporter::validateReport()
U8 category = (U8)category_sd.asInteger();
if (category == 0)
{
- if ( mReportType != BUG_REPORT )
- {
- LLNotifications::instance().add("HelpReportAbuseSelectCategory");
- }
- else
- {
- LLNotifications::instance().add("HelpReportBugSelectCategory");
- }
+ LLNotifications::instance().add("HelpReportAbuseSelectCategory");
return false;
}
@@ -561,27 +544,13 @@ bool LLFloaterReporter::validateReport()
if ( childGetText("summary_edit").empty() )
{
- if ( mReportType != BUG_REPORT )
- {
- LLNotifications::instance().add("HelpReportAbuseSummaryEmpty");
- }
- else
- {
- LLNotifications::instance().add("HelpReportBugSummaryEmpty");
- }
+ LLNotifications::instance().add("HelpReportAbuseSummaryEmpty");
return false;
};
if ( childGetText("details_edit") == mDefaultSummary )
{
- if ( mReportType != BUG_REPORT )
- {
- LLNotifications::instance().add("HelpReportAbuseDetailsEmpty");
- }
- else
- {
- LLNotifications::instance().add("HelpReportBugDetailsEmpty");
- }
+ LLNotifications::instance().add("HelpReportAbuseDetailsEmpty");
return false;
};
return true;
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index f363b9531e..7e8f05e3fc 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -1,7 +1,7 @@
/**
* @file llfloaterreporter.h
* @author Andrew Meadows
- * @brief Bug and abuse reports.
+ * @brief Abuse reports.
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
@@ -48,7 +48,7 @@ class LLMeanCollisionData;
struct LLResourceData;
// these flags are used to label info requests to the server
-const U32 BUG_REPORT_REQUEST = 0x01 << 0;
+//const U32 BUG_REPORT_REQUEST = 0x01 << 0; // DEPRECATED
const U32 COMPLAINT_REPORT_REQUEST = 0x01 << 1;
const U32 OBJECT_PAY_REQUEST = 0x01 << 2;
@@ -73,7 +73,7 @@ enum EReportType
{
NULL_REPORT = 0, // don't use this value anywhere
UNKNOWN_REPORT = 1,
- BUG_REPORT = 2,
+ //BUG_REPORT = 2, // DEPRECATED
COMPLAINT_REPORT = 3,
CS_REQUEST_REPORT = 4
};
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index f334344279..7dc29379e4 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -44,9 +44,11 @@
#include "llcombobox.h"
#include "lldraghandle.h"
#include "llfloaterbuildoptions.h"
+#include "llfloatermediasettings.h"
#include "llfloateropenobject.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
+#include "llmediaentry.h"
#include "llmenugl.h"
#include "llpanelcontents.h"
#include "llpanelface.h"
@@ -97,7 +99,7 @@ const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] =
};
// Local prototypes
-void commit_select_component(LLUICtrl *ctrl, void *data);
+void commit_select_component(void *data);
void click_show_more(void*);
void click_popup_info(void*);
void click_popup_done(void*);
@@ -105,15 +107,14 @@ void click_popup_minimize(void*);
void click_popup_rotate_left(void*);
void click_popup_rotate_reset(void*);
void click_popup_rotate_right(void*);
-void commit_slider_dozer_size(LLUICtrl *, void*);
-void commit_slider_dozer_force(LLUICtrl *, void*);
+void commit_slider_dozer_force(LLUICtrl *);
void click_apply_to_selection(void*);
-void commit_radio_group_focus(LLUICtrl* ctrl, void* data);
-void commit_radio_group_move(LLUICtrl* ctrl, void* data);
-void commit_radio_group_edit(LLUICtrl* ctrl, void* data);
-void commit_radio_group_land(LLUICtrl* ctrl, void* data);
-void commit_grid_mode(LLUICtrl *, void*);
-void commit_slider_zoom(LLUICtrl *, void*);
+void commit_radio_group_focus(LLUICtrl* ctrl);
+void commit_radio_group_move(LLUICtrl* ctrl);
+void commit_radio_group_edit(LLUICtrl* ctrl);
+void commit_radio_group_land(LLUICtrl* ctrl);
+void commit_grid_mode(LLUICtrl *);
+void commit_slider_zoom(LLUICtrl *ctrl);
//static
@@ -210,43 +211,28 @@ BOOL LLFloaterTools::postBuild()
getDragHandle()->setEnabled( !gSavedSettings.getBOOL("ToolboxAutoMove") );
LLRect rect;
- mBtnFocus = getChild<LLButton>("button focus");//btn;
- childSetAction("button focus",LLFloaterTools::setEditTool, (void*)LLToolCamera::getInstance());
- mBtnMove = getChild<LLButton>("button move");
- childSetAction("button move",LLFloaterTools::setEditTool, (void*)LLToolGrab::getInstance());
- mBtnEdit = getChild<LLButton>("button edit");
- childSetAction("button edit",LLFloaterTools::setEditTool, (void*)LLToolCompTranslate::getInstance());
- mBtnCreate = getChild<LLButton>("button create");
- childSetAction("button create",LLFloaterTools::setEditTool, (void*)LLToolCompCreate::getInstance());
- mBtnLand = getChild<LLButton>("button land" );
- childSetAction("button land",LLFloaterTools::setEditTool, (void*)LLToolSelectLand::getInstance());
- mTextStatus = getChild<LLTextBox>("text status");
-
- childSetCommitCallback("slider zoom",commit_slider_zoom,this);
-
- mRadioGroupFocus = getChild<LLRadioGroup>("focus_radio_group");
- childSetCommitCallback("focus_radio_group", commit_radio_group_focus, this);
-
- mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
- childSetCommitCallback("move_radio_group", commit_radio_group_move, this);
-
- mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
- childSetCommitCallback("edit_radio_group", commit_radio_group_edit, this);
-
- mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts");
+ mBtnFocus = getChild<LLButton>("button focus");//btn;
+ mBtnMove = getChild<LLButton>("button move");
+ mBtnEdit = getChild<LLButton>("button edit");
+ mBtnCreate = getChild<LLButton>("button create");
+ mBtnLand = getChild<LLButton>("button land" );
+ mTextStatus = getChild<LLTextBox>("text status");
+ mRadioGroupFocus = getChild<LLRadioGroup>("focus_radio_group");
+ mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
+ mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
+ mBtnGridOptions = getChild<LLButton>("Options...");
+
+ mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts");
childSetValue("checkbox edit linked parts",(BOOL)gSavedSettings.getBOOL("EditLinkedParts"));
- childSetCommitCallback("checkbox edit linked parts",commit_select_component,this);
- mCheckSnapToGrid = getChild<LLCheckBoxCtrl>("checkbox snap to grid");
+ mCheckSnapToGrid = getChild<LLCheckBoxCtrl>("checkbox snap to grid");
childSetValue("checkbox snap to grid",(BOOL)gSavedSettings.getBOOL("SnapEnabled"));
- mBtnGridOptions = getChild<LLButton>("Options...");
- childSetAction("Options...",onClickGridOptions, this);
- mCheckStretchUniform = getChild<LLCheckBoxCtrl>("checkbox uniform");
+ mCheckStretchUniform = getChild<LLCheckBoxCtrl>("checkbox uniform");
childSetValue("checkbox uniform",(BOOL)gSavedSettings.getBOOL("ScaleUniform"));
- mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures");
+ mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures");
childSetValue("checkbox stretch textures",(BOOL)gSavedSettings.getBOOL("ScaleStretchTextures"));
- mTextGridMode = getChild<LLTextBox>("text ruler mode");
- mComboGridMode = getChild<LLComboBox>("combobox grid mode");
- childSetCommitCallback("combobox grid mode",commit_grid_mode, this);
+ mTextGridMode = getChild<LLTextBox>("text ruler mode");
+ mComboGridMode = getChild<LLComboBox>("combobox grid mode");
+
//
// Create Buttons
//
@@ -271,18 +257,11 @@ BOOL LLFloaterTools::postBuild()
mCheckCopyRotates = getChild<LLCheckBoxCtrl>("checkbox copy rotates");
childSetValue("checkbox copy rotates",(BOOL)gSavedSettings.getBOOL("CreateToolCopyRotates"));
- mRadioGroupLand = getChild<LLRadioGroup>("land_radio_group");
- childSetCommitCallback("land_radio_group", commit_radio_group_land, this);
-
- mBtnApplyToSelection = getChild<LLButton>("button apply to selection");
- childSetAction("button apply to selection",click_apply_to_selection, (void*)0);
-
- mSliderDozerSize = getChild<LLSlider>("slider brush size");
- childSetCommitCallback("slider brush size", commit_slider_dozer_size, (void*)0);
+ mRadioGroupLand = getChild<LLRadioGroup>("land_radio_group");
+ mBtnApplyToSelection = getChild<LLButton>("button apply to selection");
+ mSliderDozerSize = getChild<LLSlider>("slider brush size");
childSetValue( "slider brush size", gSavedSettings.getF32("LandBrushSize"));
-
- mSliderDozerForce = getChild<LLSlider>("slider force");
- childSetCommitCallback("slider force",commit_slider_dozer_force, (void*)0);
+ mSliderDozerForce = getChild<LLSlider>("slider force");
// the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here
childSetValue( "slider force", log10(gSavedSettings.getF32("LandBrushForce")));
@@ -369,6 +348,22 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mFactoryMap["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo
//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",FALSE);
+ mCommitCallbackRegistrar.add("BuildTool.setTool", boost::bind(&LLFloaterTools::setTool,this, _2));
+ mCommitCallbackRegistrar.add("BuildTool.commitZoom", boost::bind(&commit_slider_zoom, _1));
+ mCommitCallbackRegistrar.add("BuildTool.commitRadioFocus", boost::bind(&commit_radio_group_focus, _1));
+ mCommitCallbackRegistrar.add("BuildTool.commitRadioMove", boost::bind(&commit_radio_group_move,_1));
+ mCommitCallbackRegistrar.add("BuildTool.commitRadioEdit", boost::bind(&commit_radio_group_edit,_1));
+
+ mCommitCallbackRegistrar.add("BuildTool.selectComponent", boost::bind(&commit_select_component, this));
+ mCommitCallbackRegistrar.add("BuildTool.gridOptions", boost::bind(&LLFloaterTools::onClickGridOptions,this));
+ mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this));
+ mCommitCallbackRegistrar.add("BuildTool.gridMode", boost::bind(&commit_grid_mode,_1));
+ mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1));
+ mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1));
+ mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
+ mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
+ mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
+
}
LLFloaterTools::~LLFloaterTools()
@@ -427,6 +422,7 @@ void LLFloaterTools::refresh()
mPanelObject->refresh();
mPanelVolume->refresh();
mPanelFace->refresh();
+ refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
}
@@ -756,6 +752,7 @@ void LLFloaterTools::onClose()
LLToolMgr::getInstance()->getCurrentToolset()->selectFirstTool();
//gMenuBarView->setItemVisible("BuildTools", FALSE);
+ LLFloaterReg::hideInstance("media_settings");
}
void click_popup_info(void*)
@@ -767,7 +764,7 @@ void click_popup_done(void*)
handle_reset_view();
}
-void commit_radio_group_move(LLUICtrl* ctrl, void* data)
+void commit_radio_group_move(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
@@ -788,7 +785,7 @@ void commit_radio_group_move(LLUICtrl* ctrl, void* data)
}
}
-void commit_radio_group_focus(LLUICtrl* ctrl, void* data)
+void commit_radio_group_focus(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
@@ -812,7 +809,7 @@ void commit_radio_group_focus(LLUICtrl* ctrl, void* data)
}
}
-void commit_slider_zoom(LLUICtrl *ctrl, void*)
+void commit_slider_zoom(LLUICtrl *ctrl)
{
// renormalize value, since max "volume" level is 0.5 for some reason
F32 zoom_level = (F32)ctrl->getValue().asReal() * 2.f; // / 0.5f;
@@ -837,26 +834,19 @@ void click_popup_rotate_right(void*)
dialog_refresh_all();
}
-
-void commit_slider_dozer_size(LLUICtrl *ctrl, void*)
-{
- F32 size = (F32)ctrl->getValue().asReal();
- gSavedSettings.setF32("LandBrushSize", size);
-}
-
-void commit_slider_dozer_force(LLUICtrl *ctrl, void*)
+void commit_slider_dozer_force(LLUICtrl *ctrl)
{
// the slider is logarithmic, so we exponentiate to get the actual force multiplier
F32 dozer_force = pow(10.f, (F32)ctrl->getValue().asReal());
gSavedSettings.setF32("LandBrushForce", dozer_force);
}
-void click_apply_to_selection(void* user)
+void click_apply_to_selection(void*)
{
LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal();
}
-void commit_radio_group_edit(LLUICtrl *ctrl, void *data)
+void commit_radio_group_edit(LLUICtrl *ctrl)
{
S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
@@ -881,7 +871,7 @@ void commit_radio_group_edit(LLUICtrl *ctrl, void *data)
gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
}
-void commit_radio_group_land(LLUICtrl* ctrl, void* data)
+void commit_radio_group_land(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
@@ -909,7 +899,7 @@ void commit_radio_group_land(LLUICtrl* ctrl, void* data)
}
}
-void commit_select_component(LLUICtrl *ctrl, void *data)
+void commit_select_component(void *data)
{
LLFloaterTools* floaterp = (LLFloaterTools*)data;
@@ -933,7 +923,7 @@ void commit_select_component(LLUICtrl *ctrl, void *data)
}
}
-void commit_grid_mode(LLUICtrl *ctrl, void *data)
+void commit_grid_mode(LLUICtrl *ctrl)
{
LLComboBox* combo = (LLComboBox*)ctrl;
@@ -948,10 +938,9 @@ void LLFloaterTools::setObjectType( LLPCode pcode )
gFocusMgr.setMouseCapture(NULL);
}
-// static
-void LLFloaterTools::onClickGridOptions(void* data)
+
+void LLFloaterTools::onClickGridOptions()
{
- //LLFloaterTools* floaterp = (LLFloaterTools*)data;
LLFloaterReg::showInstance("build_options");
// RN: this makes grid options dependent on build tools window
//floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE);
@@ -964,8 +953,558 @@ void LLFloaterTools::setEditTool(void* tool_pointer)
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool );
}
+void LLFloaterTools::setTool(const LLSD& user_data)
+{
+ std::string control_name = user_data.asString();
+ if(control_name == "Focus")
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool((LLTool *) LLToolCamera::getInstance() );
+ else if (control_name == "Move" )
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *)LLToolGrab::getInstance() );
+ else if (control_name == "Edit" )
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompTranslate::getInstance());
+ else if (control_name == "Create" )
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompCreate::getInstance());
+ else if (control_name == "Land" )
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolSelectLand::getInstance());
+ else
+ llwarns<<" no parameter name "<<control_name<<" found!! No Tool selected!!"<< llendl;
+}
+
void LLFloaterTools::onFocusReceived()
{
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
LLFloater::onFocusReceived();
}
+
+// Media stuff
+void LLFloaterTools::refreshMedia()
+{
+ getMediaState();
+ LLFloaterMediaSettings::getInstance();
+ LLFloaterMediaSettings::initValues(mMediaSettings );
+}
+
+
+
+void LLFloaterTools::getMediaState()
+{
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+
+ if( !objectp )
+ {
+ childSetEnabled("media_tex", FALSE);
+ childSetEnabled("add_media", FALSE);
+ childSetEnabled("delete_media", FALSE);
+ childSetEnabled("edit_media", FALSE);
+ updateMediaSettings();
+ return;
+ }
+
+ bool editable = gAgent.isGodlike() || (objectp->permModify() && objectp->getPCode() == LL_PCODE_VOLUME);
+
+ // Media settings
+ U8 has_media = (U8)0;
+ struct media_functor : public LLSelectedTEGetFunctor<U8>
+ {
+ U8 get(LLViewerObject* object, S32 face)
+ {
+ return (object->getTE(face)->getMediaTexGen());
+ }
+ } func;
+ bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, has_media );
+
+ // update UI depending on whether "object" (prim or face) has media
+ // and whether or not you are allowed to edit it.
+ bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA);
+ childSetEnabled("media_tex", bool_has_media & editable);
+ childSetEnabled( "edit_media", bool_has_media & editable );
+ childSetEnabled( "delete_media", bool_has_media & editable );
+ childSetEnabled( "add_media", ( ! bool_has_media ) & editable );
+
+ // load values for media settings
+ updateMediaSettings();
+
+ // if identical is set, all faces are same
+ if ( identical )
+ {
+ // TODO: display a list of all media on the face - use 'identical' flag
+ };
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to add media to a prim or prim face
+void LLFloaterTools::onClickBtnAddMedia()
+{
+ // check for the edit tool and now many faces are selected
+ LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+ if((tool != LLToolFace::getInstance()) || LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
+ {
+ LLNotifications::instance().add("MultipleFacesSelected",LLSD(), LLSD(), multipleFacesSelectedConfirm);
+
+ }
+ else
+ {
+ onClickBtnEditMedia();
+ }
+
+}
+
+// static
+bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ switch( option )
+ {
+ case 0: // "Yes"
+ gFloaterTools->onClickBtnEditMedia();
+ break;
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to edit existing media settings on a prim or prim face
+// TODO: test if there is media on the item and only allow editing if present
+void LLFloaterTools::onClickBtnEditMedia()
+{
+ refreshMedia();
+ LLFloaterReg::showInstance("media_settings");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to delete media from a prim or prim face
+void LLFloaterTools::onClickBtnDeleteMedia()
+{
+ LLNotifications::instance().add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
+}
+
+
+// static
+bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ switch( option )
+ {
+ case 0: // "Yes"
+ LLSelectMgr::getInstance()->selectionSetMedia( 0 );
+ if(LLFloaterReg::instanceVisible("media_settings"))
+ {
+ LLFloaterReg::hideInstance("media_settings");
+ }
+ break;
+
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLFloaterTools::updateMediaSettings()
+{
+ bool identical( false );
+ std::string base_key( "" );
+ std::string value_str( "" );
+ int value_int = 0;
+ bool value_bool = false;
+ LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
+ // TODO: (CP) refactor this using something clever or boost or both !!
+
+ LLMediaEntry default_media_data;
+
+ // controls
+ U8 value_u8 = default_media_data.getControls();
+ struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
+ {
+ U8 get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getControls();
+ LLMediaEntry default_media_data;
+ return default_media_data.getControls();
+ };
+
+ } func_controls;
+ identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
+ base_key = std::string( LLMediaEntry::CONTROLS_KEY );
+ mMediaSettings[ base_key ] = value_u8;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // First click (formerly left click)
+ value_bool = default_media_data.getFirstClickInteract();
+ struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getFirstClickInteract();
+ LLMediaEntry default_media_data;
+ return default_media_data.getFirstClickInteract();
+ };
+
+ } func_first_click;
+ identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
+ base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Home URL
+ value_str = default_media_data.getHomeURL();
+ struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ std::string get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getHomeURL();
+ LLMediaEntry default_media_data;
+ return default_media_data.getHomeURL();
+ };
+
+ } func_home_url;
+ identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
+ base_key = std::string( LLMediaEntry::HOME_URL_KEY );
+ mMediaSettings[ base_key ] = value_str;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+ llwarns<<"Angela debug : home url string == "<<value_str<<llendl;
+
+ // Current URL
+ value_str = default_media_data.getCurrentURL();
+ struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ std::string get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getCurrentURL();
+ LLMediaEntry default_media_data;
+ return default_media_data.getCurrentURL();
+ };
+
+ } func_current_url;
+ identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
+ base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
+ mMediaSettings[ base_key ] = value_str;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Auto zoom
+ value_bool = default_media_data.getAutoZoom();
+ struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getAutoZoom();
+ LLMediaEntry default_media_data;
+ return default_media_data.getAutoZoom();
+ };
+
+ } func_auto_zoom;
+ identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
+ base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Auto play
+ value_bool = default_media_data.getAutoPlay();
+ struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getAutoPlay();
+ LLMediaEntry default_media_data;
+ return default_media_data.getAutoPlay();
+ };
+
+ } func_auto_play;
+ identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );
+ base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Auto scale
+ value_bool = default_media_data.getAutoScale();
+ struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getAutoScale();
+ LLMediaEntry default_media_data;
+ return default_media_data.getAutoScale();;
+ };
+
+ } func_auto_scale;
+ identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );
+ base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Auto loop
+ value_bool = default_media_data.getAutoLoop();
+ struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getAutoLoop();
+ LLMediaEntry default_media_data;
+ return default_media_data.getAutoLoop();
+ };
+
+ } func_auto_loop;
+ identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );
+ base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // width pixels (if not auto scaled)
+ value_int = default_media_data.getWidthPixels();
+ struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ int get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getWidthPixels();
+ LLMediaEntry default_media_data;
+ return default_media_data.getWidthPixels();
+ };
+
+ } func_width_pixels;
+ identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );
+ base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );
+ mMediaSettings[ base_key ] = value_int;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // height pixels (if not auto scaled)
+ value_int = default_media_data.getHeightPixels();
+ struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ int get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getHeightPixels();
+ LLMediaEntry default_media_data;
+ return default_media_data.getHeightPixels();
+ };
+
+ } func_height_pixels;
+ identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );
+ base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );
+ mMediaSettings[ base_key ] = value_int;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Enable Alt image
+ value_bool = default_media_data.getAltImageEnable();
+ struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getAltImageEnable();
+ LLMediaEntry default_media_data;
+ return default_media_data.getAltImageEnable();
+ };
+
+ } func_enable_alt_image;
+ identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );
+ base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - owner interact
+ value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
+ struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
+ LLMediaEntry default_media_data;
+ return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
+ };
+
+ } func_perms_owner_interact;
+ identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - owner control
+ value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
+ struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
+ LLMediaEntry default_media_data;
+ return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
+ };
+
+ } func_perms_owner_control;
+ identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - group interact
+ value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
+ struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
+ LLMediaEntry default_media_data;
+ return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
+ };
+
+ } func_perms_group_interact;
+ identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - group control
+ value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
+ struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
+ LLMediaEntry default_media_data;
+ return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
+ };
+
+ } func_perms_group_control;
+ identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - anyone interact
+ value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
+ struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
+ LLMediaEntry default_media_data;
+ return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
+ };
+
+ } func_perms_anyone_interact;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - anyone control
+ value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
+ struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
+ LLMediaEntry default_media_data;
+ return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
+ };
+
+ } func_perms_anyone_control;
+ identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // security - whitelist enable
+ value_bool = default_media_data.getWhiteListEnable();
+ struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
+ {
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getWhiteListEnable();
+ LLMediaEntry default_media_data;
+ return default_media_data.getWhiteListEnable();
+ };
+
+ } func_whitelist_enable;
+ identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );
+ base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // security - whitelist URLs
+ std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
+ struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
+ {
+ std::vector<std::string> get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getWhiteList();
+ LLMediaEntry default_media_data;
+ return default_media_data.getWhiteList();
+ };
+
+ } func_whitelist_urls;
+ identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );
+ base_key = std::string( LLMediaEntry::WHITELIST_KEY );
+ mMediaSettings[ base_key ].clear();
+ std::vector< std::string >::iterator iter = value_vector_str.begin();
+ while( iter != value_vector_str.end() )
+ {
+ std::string white_list_url = *iter;
+ mMediaSettings[ base_key ].append( white_list_url );
+ ++iter;
+ };
+
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+}
+
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index 1b9f1d31ec..008c9677ed 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -100,13 +100,24 @@ public:
void setStatusText(const std::string& text);
static void setEditTool(void* data);
+ void setTool(const LLSD& user_data);
void saveLastTool();
+ void onClickBtnDeleteMedia();
+ void onClickBtnAddMedia();
+ void onClickBtnEditMedia();
+
+
private:
void onClose();
void refresh();
-
+ void refreshMedia();
+ void getMediaState();
+ void updateMediaSettings();
+ void getMeidaState();
+ static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
+ static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
- static void onClickGridOptions(void* data);
+ void onClickGridOptions();
public:
LLButton *mBtnFocus;
@@ -175,6 +186,10 @@ private:
BOOL mDirty;
std::map<std::string, std::string> mStatusText;
+
+protected:
+ LLSD mMediaSettings;
+
};
extern LLFloaterTools *gFloaterTools;
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index 1e975cd447..2b01a56373 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -35,6 +35,7 @@
#include "llfloaterurlentry.h"
#include "llpanellandmedia.h"
+#include "llpanelface.h"
// project includes
#include "llcombobox.h"
@@ -145,13 +146,23 @@ void LLFloaterURLEntry::buildURLHistory()
void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type)
{
- LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
+ LLPanelLandMedia* panel_media = dynamic_cast<LLPanelLandMedia*>(mPanelLandMediaHandle.get());
if (panel_media)
{
// status is ignored for now -- error = "none/none"
panel_media->setMediaType(mime_type);
panel_media->setMediaURL(mMediaURLEdit->getValue().asString());
}
+ else
+ {
+ LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get());
+ if(panel_face)
+ {
+ panel_face->setMediaType(mime_type);
+ panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
+ }
+
+ }
// Decrement the cursor
getWindow()->decBusyCount();
childSetVisible("loading_label", false);
@@ -159,29 +170,18 @@ void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_
}
// static
-LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent)
+LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent, const std::string media_url)
{
- if (sInstance)
- {
- sInstance->openFloater();
- }
- else
+ if (!sInstance)
{
sInstance = new LLFloaterURLEntry(parent);
}
- sInstance->updateFromLandMediaPanel();
+ sInstance->openFloater();
+ sInstance->addURLToCombobox(media_url);
return sInstance->getHandle();
}
-void LLFloaterURLEntry::updateFromLandMediaPanel()
-{
- LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
- if (panel_media)
- {
- std::string media_url = panel_media->getMediaURL();
- addURLToCombobox(media_url);
- }
-}
+
bool LLFloaterURLEntry::addURLToCombobox(const std::string& media_url)
{
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index 0aeca823b8..6dd9c8453c 100644
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
@@ -44,10 +44,8 @@ class LLFloaterURLEntry : public LLFloater
public:
// Can only be shown by LLPanelLandMedia, and pushes data back into
// that panel via the handle.
- static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle);
+ static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle, const std::string media_url);
/*virtual*/ BOOL postBuild();
- void updateFromLandMediaPanel();
-
void headerFetchComplete(U32 status, const std::string& mime_type);
bool addURLToCombobox(const std::string& media_url);
diff --git a/indra/newview/llfloaterwhitelistentry.cpp b/indra/newview/llfloaterwhitelistentry.cpp
new file mode 100644
index 0000000000..551a5191fc
--- /dev/null
+++ b/indra/newview/llfloaterwhitelistentry.cpp
@@ -0,0 +1,97 @@
+/**
+ * @file llfloaterwhitelistentry.cpp
+ * @brief LLFloaterWhistListEntry class implementation
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterreg.h"
+#include "llfloatermediasettings.h"
+#include "llfloaterwhitelistentry.h"
+#include "llpanelmediasettingssecurity.h"
+#include "lluictrlfactory.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "lllineeditor.h"
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterWhiteListEntry::LLFloaterWhiteListEntry( const LLSD& key ) :
+ LLFloater(key)
+{
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_whitelist_entry.xml");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterWhiteListEntry::~LLFloaterWhiteListEntry()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLFloaterWhiteListEntry::postBuild()
+{
+ mWhiteListEdit = getChild<LLLineEditor>("whitelist_entry");
+
+ childSetAction("cancel_btn", onBtnCancel, this);
+ childSetAction("ok_btn", onBtnOK, this);
+
+ setDefaultBtn("ok_btn");
+
+ return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterWhiteListEntry::onBtnOK( void* userdata )
+{
+ LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata;
+
+ LLPanelMediaSettingsSecurity* panel = LLFloaterReg::getTypedInstance<LLFloaterMediaSettings>("media_settings")->getPanelSecurity();
+ if ( panel )
+ {
+ std::string white_list_item = self->mWhiteListEdit->getText();
+
+ panel->addWhiteListItem( white_list_item );
+ };
+
+ self->closeFloater();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterWhiteListEntry::onBtnCancel( void* userdata )
+{
+ LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata;
+
+ self->closeFloater();
+}
diff --git a/indra/newview/llfloaterwhitelistentry.h b/indra/newview/llfloaterwhitelistentry.h
new file mode 100644
index 0000000000..8ab5fb78b9
--- /dev/null
+++ b/indra/newview/llfloaterwhitelistentry.h
@@ -0,0 +1,56 @@
+/**
+ * @file llfloaterwhitelistentry.h
+ * @brief LLFloaterWhiteListEntry class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERWHITELISTENTRY_H
+#define LL_LLFLOATERWHITELISTENTRY_H
+
+#include "llfloater.h"
+
+class LLLineEditor;
+
+class LLFloaterWhiteListEntry :
+ public LLFloater
+{
+ public:
+ LLFloaterWhiteListEntry(const LLSD& key);
+ ~LLFloaterWhiteListEntry();
+
+ BOOL postBuild();
+
+ private:
+ LLLineEditor* mWhiteListEdit;
+
+ static void onBtnOK(void*);
+ static void onBtnCancel(void*);
+};
+
+#endif // LL_LLFLOATERWHITELISTENTRY_H
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 2a29566120..d149c8bbb5 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -1318,7 +1318,7 @@ void LLFolderView::startRenamingSelectedItem( void )
mRenamer->setVisible( TRUE );
// set focus will fail unless item is visible
mRenamer->setFocus( TRUE );
- mRenamer->setTopLostCallback(onRenamerLost);
+ mRenamer->setTopLostCallback(boost::bind(onRenamerLost, _1));
gFocusMgr.setTopCtrl( mRenamer );
}
}
@@ -2147,7 +2147,7 @@ void LLFolderView::updateRenamerPosition()
///----------------------------------------------------------------------------
//static
-void LLFolderView::onRenamerLost( LLFocusableElement* renamer, void* user_data)
+void LLFolderView::onRenamerLost( LLFocusableElement* renamer)
{
LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(renamer);
if (uictrl)
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index a05dec3193..69c0c5b132 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -279,7 +279,7 @@ protected:
LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container.
void commitRename( const LLSD& data );
- static void onRenamerLost( LLFocusableElement* renamer, void* user_data);
+ static void onRenamerLost( LLFocusableElement* renamer);
void finishRenamingItem( void );
void closeRenamer( void );
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index d3b013237b..905857f393 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -73,7 +73,11 @@ LLGroupList::Params::Params()
LLGroupList::LLGroupList(const Params& p)
: LLFlatListView(p)
+ , mDirty(true) // to force initial update
{
+ // Listen for agent group changes.
+ gAgent.addListener(this, "new group");
+
mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
setCommitOnSelectionChange(true);
// TODO: implement context menu
@@ -84,17 +88,41 @@ LLGroupList::LLGroupList(const Params& p)
setComparator(&GROUP_COMPARATOR);
}
+LLGroupList::~LLGroupList()
+{
+ gAgent.removeListener(this);
+}
+
+// virtual
+void LLGroupList::draw()
+{
+ if (mDirty)
+ refresh();
+
+ LLFlatListView::draw();
+}
+
+void LLGroupList::setNameFilter(const std::string& filter)
+{
+ if (mNameFilter != filter)
+ {
+ mNameFilter = filter;
+ setDirty();
+ }
+}
+
static bool findInsensitive(std::string haystack, const std::string& needle_upper)
{
LLStringUtil::toUpper(haystack);
return haystack.find(needle_upper) != std::string::npos;
}
-BOOL LLGroupList::update(const std::string& name_filter)
+void LLGroupList::refresh()
{
const LLUUID& highlight_id = gAgent.getGroupID();
S32 count = gAgent.mGroups.count();
LLUUID id;
+ bool have_filter = !mNameFilter.empty();
clear();
@@ -102,7 +130,7 @@ BOOL LLGroupList::update(const std::string& name_filter)
{
id = gAgent.mGroups.get(i).mID;
const LLGroupData& group_data = gAgent.mGroups.get(i);
- if (name_filter != LLStringUtil::null && !findInsensitive(group_data.mName, name_filter))
+ if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
continue;
addNewItem(id, group_data.mName, group_data.mInsigniaID, highlight_id == id, ADD_BOTTOM);
}
@@ -113,13 +141,14 @@ BOOL LLGroupList::update(const std::string& name_filter)
// add "none" to list at top
{
std::string loc_none = LLTrans::getString("GroupsNone");
- if (name_filter == LLStringUtil::null || findInsensitive(loc_none, name_filter))
+ if (have_filter || findInsensitive(loc_none, mNameFilter))
addNewItem(LLUUID::null, loc_none, LLUUID::null, highlight_id.isNull(), ADD_TOP);
}
selectItemByUUID(highlight_id);
- return TRUE;
+ setDirty(false);
+ onCommit();
}
void LLGroupList::toggleIcons()
@@ -158,6 +187,18 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
// setCommentVisible(false);
}
+// virtual
+bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ // Why is "new group" sufficient?
+ if (event->desc() == "new group")
+ {
+ setDirty();
+ return true;
+ }
+
+ return false;
+}
/************************************************************************/
/* LLGroupListItem implementation */
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 7708b58de6..9c3ab88901 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -33,10 +33,19 @@
#ifndef LL_LLGROUPLIST_H
#define LL_LLGROUPLIST_H
+#include "llevent.h"
#include "llflatlistview.h"
#include "llpanel.h"
+#include "llpointer.h"
-class LLGroupList: public LLFlatListView
+/**
+ * Auto-updating list of agent groups.
+ *
+ * Can use optional group name filter.
+ *
+ * @see setNameFilter()
+ */
+class LLGroupList: public LLFlatListView, public LLOldEvents::LLSimpleListener
{
LOG_CLASS(LLGroupList);
public:
@@ -46,14 +55,23 @@ public:
};
LLGroupList(const Params& p);
- BOOL update(const std::string& name_filter = LLStringUtil::null);
+ virtual ~LLGroupList();
+
+ virtual void draw(); // from LLView
+
+ void setNameFilter(const std::string& filter);
void toggleIcons();
bool getIconsVisible() const { return mShowIcons; }
-
+
private:
+ void setDirty(bool val = true) { mDirty = val; }
+ void refresh();
void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
bool mShowIcons;
+ bool mDirty;
+ std::string mNameFilter;
};
class LLButton;
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 29102feb64..d0be581f6d 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -48,6 +48,7 @@
#include "lltrans.h"
#include "llviewertexteditor.h"
#include "llviewerwindow.h"
+#include "lltransientfloatermgr.h"
@@ -62,33 +63,44 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
mInputEditor(NULL),
mPositioned(false)
{
- LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
- if(session)
+ EInstantMessage type = LLIMModel::getInstance()->getType(session_id);
+ if(IM_COUNT != type)
{
- mDialog = session->mType;
- }
+ mDialog = type;
- if (mDialog == IM_NOTHING_SPECIAL)
- {
- mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
- }
- else
- {
- mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
+ if (IM_NOTHING_SPECIAL == mDialog || IM_SESSION_P2P_INVITE == mDialog)
+ {
+ mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
+ }
+ else
+ {
+ mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
+ }
}
-// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml");
-
- gFocusMgr.addFocusChangeCallback(boost::bind(&LLIMFloater::focusChangeCallback, this));
mCloseSignal.connect(boost::bind(&LLIMFloater::onClose, this));
+
+ LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);
}
void LLIMFloater::onClose()
{
LLIMModel::instance().sendLeaveSession(mSessionID, mOtherParticipantUUID);
+
+ //*TODO - move to the IMModel::sendLeaveSession() for the integrity (IB)
gIMMgr->removeSession(mSessionID);
}
+void LLIMFloater::setMinimized(BOOL minimize)
+{
+ if(!isDocked())
+ {
+ setVisible(!minimize);
+ }
+
+ LLFloater::setMinimized(minimize);
+}
+
/* static */
void LLIMFloater::newIMCallback(const LLSD& data){
@@ -152,16 +164,17 @@ void LLIMFloater::sendMsg()
LLIMFloater::~LLIMFloater()
{
+ LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
}
//virtual
BOOL LLIMFloater::postBuild()
{
- LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
- if(session)
+ const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
+ if (other_party_id.notNull())
{
- mOtherParticipantUUID = session->mOtherParticipantID;
- mControlPanel->setID(session->mOtherParticipantID);
+ mOtherParticipantUUID = other_party_id;
+ mControlPanel->setID(mOtherParticipantUUID);
}
LLButton* slide_left = getChild<LLButton>("slide_left_btn");
@@ -177,8 +190,8 @@ BOOL LLIMFloater::postBuild()
// enable line history support for instant message bar
mInputEditor->setEnableLineHistory(TRUE);
- mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
- mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
+ mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
+ mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
mInputEditor->setCommitOnFocusLost( FALSE );
mInputEditor->setRevertOnEsc( FALSE );
@@ -216,17 +229,6 @@ void* LLIMFloater::createPanelGroupControl(void* userdata)
return self->mControlPanel;
}
-
-
-void LLIMFloater::focusChangeCallback()
-{
- // hide docked floater if user clicked inside in-world area
- if (isDocked() && gFocusMgr.getKeyboardFocus() == NULL)
- {
- setVisible(false);
- }
-}
-
void LLIMFloater::onSlide()
{
LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
@@ -271,13 +273,13 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
}
floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
- LLDockControl::TOP, boost::bind(&LLIMFloater::getEnabledRect, floater, _1)));
+ LLDockControl::TOP, boost::bind(&LLIMFloater::getAllowedRect, floater, _1)));
}
return floater;
}
-void LLIMFloater::getEnabledRect(LLRect& rect)
+void LLIMFloater::getAllowedRect(LLRect& rect)
{
rect = gViewerWindow->getWorldViewRect();
}
@@ -285,8 +287,10 @@ void LLIMFloater::getEnabledRect(LLRect& rect)
void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
{
// update notification channel state
- LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+ LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
+ (LLNotificationsUI::LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
LLDockableFloater::setDocked(docked, pop_on_undock);
// update notification channel state
@@ -298,8 +302,9 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
void LLIMFloater::setVisible(BOOL visible)
{
- LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+ LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
+ (LLNotificationsUI::LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
LLDockableFloater::setVisible(visible);
// update notification channel state
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 276f38e829..a183212f04 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -57,6 +57,8 @@ public:
// LLFloater overrides
/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
+ // override LLFloater's minimization according to EXT-1216
+ /*virtual*/ void setMinimized(BOOL minimize);
// Make IM conversion visible and update the message history
static LLIMFloater* show(const LLUUID& session_id);
@@ -90,8 +92,8 @@ private:
void onSlide();
static void* createPanelIMControl(void* userdata);
static void* createPanelGroupControl(void* userdata);
- void focusChangeCallback();
- void getEnabledRect(LLRect& rect);
+ // gets a rect that bounds possible positions for the LLIMFloater on a screen (EXT-1111)
+ void getAllowedRect(LLRect& rect);
LLPanelChatControlPanel* mControlPanel;
LLUUID mSessionID;
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 46067c081f..74971f3fd8 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -109,7 +109,9 @@ bool LLIMHandler::processNotification(const LLSD& notify)
p.panel = im_box;
p.can_be_stored = false;
p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
- mChannel->addToast(p);
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
// send a signal to the counter manager;
mNewNotificationSignal();
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index de4faf72f5..abd3cd4def 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -940,7 +940,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
mHistoryEditor(NULL),
mSessionUUID(session_id),
mSessionLabel(session_label),
- mVoiceChannel(NULL),
mSessionInitialized(FALSE),
mSessionStartMsgPos(0),
mOtherParticipantUUID(other_participant_id),
@@ -956,7 +955,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
mTextIMPossible(TRUE),
mProfileButtonEnabled(TRUE),
mCallBackEnabled(TRUE),
- mSpeakers(NULL),
mSpeakerPanel(NULL),
mFirstKeystrokeTimer(),
mLastKeystrokeTimer()
@@ -967,7 +965,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
case IM_SESSION_GROUP_START:
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
xml_filename = "floater_instant_message_group.xml";
- mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
break;
case IM_SESSION_INVITE:
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
@@ -979,16 +976,13 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
{
xml_filename = "floater_instant_message_ad_hoc.xml";
}
- mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
break;
case IM_SESSION_P2P_INVITE:
xml_filename = "floater_instant_message.xml";
- mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
break;
case IM_SESSION_CONFERENCE_START:
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
xml_filename = "floater_instant_message_ad_hoc.xml";
- mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
break;
// just received text from another user
case IM_NOTHING_SPECIAL:
@@ -998,8 +992,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionUUID);
mProfileButtonEnabled = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionUUID);
mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionUUID);
-
- mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
break;
default:
llwarns << "Unknown session type" << llendl;
@@ -1007,10 +999,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
break;
}
- mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
- // All participants will be added to the list of people we've recently interacted with.
- mSpeakers->addListener(&LLRecentPeople::instance(), "add");
-
LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, NULL);
setTitle(mSessionLabel);
@@ -1058,38 +1046,8 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
LLFloaterIMPanel::~LLFloaterIMPanel()
{
- delete mSpeakers;
- mSpeakers = NULL;
-
- // End the text IM session if necessary
- if(gVoiceClient && mOtherParticipantUUID.notNull())
- {
- switch(mDialog)
- {
- case IM_NOTHING_SPECIAL:
- case IM_SESSION_P2P_INVITE:
- gVoiceClient->endUserIMSession(mOtherParticipantUUID);
- break;
-
- default:
- // Appease the compiler
- break;
- }
- }
-
- //kicks you out of the voice channel if it is currently active
-
- // HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
- mVoiceChannel->deactivate();
-
- delete mVoiceChannel;
- mVoiceChannel = NULL;
-
//delete focus lost callback
- if(mInputEditor)
- {
- mInputEditor->setFocusLostCallback( NULL );
- }
+ mFocusCallbackConnection.disconnect();
}
BOOL LLFloaterIMPanel::postBuild()
@@ -1099,8 +1057,8 @@ BOOL LLFloaterIMPanel::postBuild()
mVisibleSignal.connect(boost::bind(&LLFloaterIMPanel::onVisibilityChange, this, _2));
mInputEditor = getChild<LLLineEditor>("chat_editor");
- mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
- mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
+ mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
+ mFocusCallbackConnection = mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this));
mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
mInputEditor->setCommitCallback( onCommitChat, this );
mInputEditor->setCommitOnFocusLost( FALSE );
@@ -1155,7 +1113,8 @@ BOOL LLFloaterIMPanel::postBuild()
void* LLFloaterIMPanel::createSpeakersPanel(void* data)
{
LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)data;
- floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(floaterp->mSpeakers, TRUE);
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(floaterp->mSessionUUID);
+ floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(speaker_mgr, TRUE);
return floaterp->mSpeakerPanel;
}
@@ -1201,12 +1160,14 @@ void LLFloaterIMPanel::draw()
&& mCallBackEnabled;
// hide/show start call and end call buttons
- childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
- childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID);
+ childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
+ childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
childSetEnabled("start_call_btn", enable_connect);
childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
- LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID());
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
+ LLPointer<LLSpeaker> self_speaker = speaker_mgr->findSpeaker(gAgent.getID());
if(!mTextIMPossible)
{
mInputEditor->setEnabled(FALSE);
@@ -1230,7 +1191,7 @@ void LLFloaterIMPanel::draw()
}
// show speakers window when voice first connects
- if (mShowSpeakersOnConnect && mVoiceChannel->isActive())
+ if (mShowSpeakersOnConnect && voice_channel->isActive())
{
childSetVisible("active_speakers_panel", TRUE);
mShowSpeakersOnConnect = FALSE;
@@ -1266,11 +1227,11 @@ void LLFloaterIMPanel::draw()
else
{
// refresh volume and mute checkbox
- childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
+ childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID));
childSetValue("mute_btn", LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat));
- childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
+ childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
}
LLFloater::draw();
}
@@ -1406,12 +1367,6 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
{
mNumUnreadMessages++;
}
-
- if (source != LLUUID::null)
- {
- mSpeakers->speakerChatted(source);
- mSpeakers->setSpeakerTyping(source, FALSE);
- }
}
@@ -1592,7 +1547,7 @@ void LLFloaterIMPanel::onClickStartCall(void* userdata)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
- self->mVoiceChannel->activate();
+ LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->activate();
}
// static
@@ -1600,7 +1555,7 @@ void LLFloaterIMPanel::onClickEndCall(void* userdata)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
- self->getVoiceChannel()->deactivate();
+ LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->deactivate();
}
// static
@@ -1674,7 +1629,8 @@ void LLFloaterIMPanel::onVisibilityChange(const LLSD& new_visibility)
mNumUnreadMessages = 0;
}
- if (new_visibility.asBoolean() && mVoiceChannel->getState() == LLVoiceChannel::STATE_CONNECTED)
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID);
+ if (new_visibility.asBoolean() && voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
LLFloaterReg::showInstance("voice_call", mSessionUUID);
else
LLFloaterReg::hideInstance("voice_call", mSessionUUID);
@@ -1726,11 +1682,6 @@ void LLFloaterIMPanel::sendMsg()
mSentTypingState = TRUE;
}
-void LLFloaterIMPanel::updateSpeakersList(const LLSD& speaker_updates)
-{
- mSpeakers->updateSpeakers(speaker_updates);
-}
-
void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
{
if (
@@ -1754,15 +1705,9 @@ void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
}
}
-void LLFloaterIMPanel::setSpeakers(const LLSD& speaker_list)
-{
- mSpeakers->setSpeakers(speaker_list);
-}
-
void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
{
mSessionUUID = session_id;
- mVoiceChannel->updateSessionID(session_id);
mSessionInitialized = TRUE;
//we assume the history editor hasn't moved at all since
@@ -1793,6 +1738,7 @@ void LLFloaterIMPanel::requestAutoConnect()
void LLFloaterIMPanel::setTyping(BOOL typing)
{
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
if (typing)
{
// Every time you type something, reset this timer
@@ -1807,7 +1753,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
mSentTypingState = FALSE;
}
- mSpeakers->setSpeakerTyping(gAgent.getID(), TRUE);
+ speaker_mgr->setSpeakerTyping(gAgent.getID(), TRUE);
}
else
{
@@ -1817,7 +1763,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
sendTypingState(FALSE);
mSentTypingState = TRUE;
}
- mSpeakers->setSpeakerTyping(gAgent.getID(), FALSE);
+ speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
}
mTyping = typing;
@@ -1877,7 +1823,7 @@ void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info)
mHistoryEditor->removeTextFromEnd(chars_to_remove);
if (im_info)
{
- mSpeakers->setSpeakerTyping(im_info->mFromID, FALSE);
+ LLIMModel::getInstance()->getSpeakerManager(mSessionUUID)->setSpeakerTyping(im_info->mFromID, FALSE);
}
}
}
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index dbf5e1cb6a..fb9b28ad16 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -33,6 +33,7 @@
#ifndef LL_IMPANEL_H
#define LL_IMPANEL_H
+#include "llimview.h" //for LLIMModel
#include "lldockablefloater.h"
#include "lllogchat.h"
#include "lluuid.h"
@@ -245,11 +246,7 @@ public:
const LLUUID& getSessionID() const { return mSessionUUID; }
const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; }
- LLIMSpeakerMgr* getSpeakerManager() const { return mSpeakers; }
- void updateSpeakersList(const LLSD& speaker_updates);
void processSessionUpdate(const LLSD& update);
- void setSpeakers(const LLSD& speaker_list);
- LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
EInstantMessage getDialogType() const { return mDialog; }
void setDialogType(EInstantMessage dialog) { mDialog = dialog; }
@@ -305,7 +302,6 @@ private:
LLUUID mSessionUUID;
std::string mSessionLabel;
- LLVoiceChannel* mVoiceChannel;
BOOL mSessionInitialized;
LLSD mQueuedMsgsForInit;
@@ -346,7 +342,6 @@ private:
BOOL mProfileButtonEnabled;
BOOL mCallBackEnabled;
- LLIMSpeakerMgr* mSpeakers;
LLPanelActiveSpeakers* mSpeakerPanel;
// Optimization: Don't send "User is typing..." until the
@@ -357,6 +352,8 @@ private:
// Timer to detect when user has stopped typing.
LLFrameTimer mLastKeystrokeTimer;
+ boost::signals2::connection mFocusCallbackConnection;
+
void disableWhileSessionStarting();
};
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 3cf78f957b..556eb5ffd7 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -114,10 +114,84 @@ void toast_callback(const LLSD& msg){
LLIMModel::LLIMModel()
{
- addChangedCallback(toast_callback);
addChangedCallback(LLIMFloater::newIMCallback);
+ addChangedCallback(toast_callback);
+}
+
+
+LLIMModel::LLIMSession::LLIMSession( const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id )
+: mSessionID(session_id),
+ mName(name),
+ mType(type),
+ mNumUnread(0),
+ mOtherParticipantID(other_participant_id),
+ mVoiceChannel(NULL),
+ mSpeakers(NULL)
+{
+ if (IM_NOTHING_SPECIAL == type || IM_SESSION_P2P_INVITE == type)
+ {
+ mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id);
+ }
+ else
+ {
+ mVoiceChannel = new LLVoiceChannelGroup(session_id, name);
+ }
+ mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
+
+ // All participants will be added to the list of people we've recently interacted with.
+ mSpeakers->addListener(&LLRecentPeople::instance(), "add");
+}
+
+LLIMModel::LLIMSession::~LLIMSession()
+{
+ delete mSpeakers;
+ mSpeakers = NULL;
+
+ // End the text IM session if necessary
+ if(gVoiceClient && mOtherParticipantID.notNull())
+ {
+ switch(mType)
+ {
+ case IM_NOTHING_SPECIAL:
+ case IM_SESSION_P2P_INVITE:
+ gVoiceClient->endUserIMSession(mOtherParticipantID);
+ break;
+
+ default:
+ // Appease the linux compiler
+ break;
+ }
+ }
+
+ // HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
+ mVoiceChannel->deactivate();
+
+ delete mVoiceChannel;
+ mVoiceChannel = NULL;
}
+LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
+{
+ return get_if_there(LLIMModel::instance().sSessionsMap, session_id,
+ (LLIMModel::LLIMSession*) NULL);
+}
+
+void LLIMModel::updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id)
+{
+ if (new_session_id == old_session_id) return;
+
+ LLIMSession* session = findIMSession(old_session_id);
+ if (session)
+ {
+ session->mSessionID = new_session_id;
+ session->mVoiceChannel->updateSessionID(new_session_id);
+
+ //*TODO set session initialized flag here? (IB)
+
+ sSessionsMap.erase(old_session_id);
+ sSessionsMap[new_session_id] = session;
+ }
+}
void LLIMModel::testMessages()
{
@@ -153,7 +227,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage
return false;
}
- LLIMSession* session = new LLIMSession(name, type, other_participant_id);
+ LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id);
sSessionsMap[session_id] = session;
LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id);
@@ -170,12 +244,12 @@ bool LLIMModel::clearSession(LLUUID session_id)
return true;
}
+//*TODO remake it, instead of returing the list pass it as as parameter (IB)
std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
{
std::list<LLSD> return_list;
- LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
-
+ LLIMSession* session = findIMSession(session_id);
if (!session)
{
llwarns << "session " << session_id << "does not exist " << llendl;
@@ -202,13 +276,14 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
mChangedSignal(arg);
// TODO: in the future is there a more efficient way to return these
+ //of course there is - return as parameter (IB)
return return_list;
}
bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string utf8_text) {
- LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+ LLIMSession* session = findIMSession(session_id);
if (!session)
{
@@ -231,7 +306,7 @@ bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string ut
bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text) {
- LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+ LLIMSession* session = findIMSession(session_id);
if (!session)
{
@@ -260,9 +335,9 @@ bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id,
}
-const std::string& LLIMModel::getName(LLUUID session_id)
+const std::string& LLIMModel::getName(const LLUUID& session_id) const
{
- LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+ LLIMSession* session = findIMSession(session_id);
if (!session)
{
@@ -273,6 +348,66 @@ const std::string& LLIMModel::getName(LLUUID session_id)
return session->mName;
}
+const S32 LLIMModel::getNumUnread(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return -1;
+ }
+
+ return session->mNumUnread;
+}
+
+const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return LLUUID::null;
+ }
+
+ return session->mOtherParticipantID;
+}
+
+EInstantMessage LLIMModel::getType(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return IM_COUNT;
+ }
+
+ return session->mType;
+}
+
+LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id ) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return NULL;
+ }
+
+ return session->mVoiceChannel;
+}
+
+LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return NULL;
+ }
+
+ return session->mSpeakers;
+}
+
// TODO get rid of other participant ID
void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing)
@@ -316,7 +451,7 @@ void LLIMModel::sendLeaveSession(LLUUID session_id, LLUUID other_participant_id)
}
-
+//*TODO update list of messages in a LLIMSession (IB)
void LLIMModel::sendMessage(const std::string& utf8_text,
const LLUUID& im_session_id,
const LLUUID& other_participant_id,
@@ -415,9 +550,16 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(im_session_id);
if (floater) floater->addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID());
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(im_session_id);
+ if (speaker_mgr)
+ {
+ speaker_mgr->speakerChatted(gAgentID);
+ speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
+ }
}
// Add the recipient to the recent people list.
+ //*TODO should be deleted, because speaker manager updates through callback the recent list
LLRecentPeople::instance().add(other_participant_id);
}
@@ -633,10 +775,8 @@ public:
{
if ( gIMMgr)
{
- LLFloaterIMPanel* floaterp =
- gIMMgr->findFloaterBySession(mSessionID);
-
- if (floaterp)
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
{
//we've accepted our invitation
//and received a list of agents that were
@@ -650,15 +790,20 @@ public:
//but unfortunately, our base that we are receiving here
//may not be the most up to date. It was accurate at
//some point in time though.
- floaterp->setSpeakers(content);
+ speaker_mgr->setSpeakers(content);
//we now have our base of users in the session
//that was accurate at some point, but maybe not now
//so now we apply all of the udpates we've received
//in case of race conditions
- floaterp->updateSpeakersList(
- gIMMgr->getPendingAgentListUpdates(mSessionID));
+ speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
+ }
+
+ LLFloaterIMPanel* floaterp =
+ gIMMgr->findFloaterBySession(mSessionID);
+ if (floaterp)
+ {
if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
{
floaterp->requestAutoConnect();
@@ -1104,6 +1249,12 @@ void LLIMMgr::addMessage(
//no session ID...compute new one
new_session_id = computeSessionID(dialog, other_participant_id);
}
+
+ if (!LLIMModel::getInstance()->findIMSession(new_session_id))
+ {
+ LLIMModel::instance().newSession(session_id, session_name, dialog, other_participant_id);
+ }
+
floater = findFloaterBySession(new_session_id);
if (!floater)
{
@@ -1169,6 +1320,14 @@ void LLIMMgr::addMessage(
else
{
floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message
+
+ //*TODO consider moving that speaker management stuff into model (IB)
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(new_session_id);
+ if (speaker_mgr)
+ {
+ speaker_mgr->speakerChatted(gAgentID);
+ speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
+ }
}
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
@@ -1273,11 +1432,10 @@ LLUUID LLIMMgr::addP2PSession(const std::string& name,
{
LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id);
- LLFloaterIMPanel* floater = findFloaterBySession(session_id);
- if(floater)
+ LLVoiceChannelP2P* voice_channel = (LLVoiceChannelP2P*) LLIMModel::getInstance()->getSpeakerManager(session_id);
+ if (voice_channel)
{
- LLVoiceChannelP2P* voice_channelp = (LLVoiceChannelP2P*)floater->getVoiceChannel();
- voice_channelp->setSessionHandle(voice_session_handle, caller_uri);
+ voice_channel->setSessionHandle(voice_session_handle, caller_uri);
}
return session_id;
@@ -1312,6 +1470,11 @@ LLUUID LLIMMgr::addSession(
LLUUID session_id = computeSessionID(dialog,other_participant_id);
+ if (!LLIMModel::getInstance()->findIMSession(session_id))
+ {
+ LLIMModel::instance().newSession(session_id, name, dialog, other_participant_id);
+ }
+
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if(!floater)
{
@@ -1335,17 +1498,10 @@ LLUUID LLIMMgr::addSession(
noteMutedUsers(floater, ids);
}
}
- else
- {
- // *TODO: Remove this? Otherwise old communicate window opens on
- // second initiation of IM session from People panel?
- // floater->openFloater();
- }
- //mTabContainer->selectTabPanel(panel);
floater->setInputFocus(TRUE);
LLIMFloater::show(session_id);
- notifyObserverSessionAdded(floater->getSessionID(), name, other_participant_id);
- return floater->getSessionID();
+
+ return session_id;
}
// This removes the panel referenced by the uuid, and then restores
@@ -1705,7 +1861,6 @@ LLFloaterIMPanel* LLIMMgr::createFloater(
LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
LLFloaterChatterBox::getInstance()->addFloater(floater, FALSE, i_pt);
mFloaters.insert(floater->getHandle());
- LLIMModel::instance().newSession(session_id, session_label, dialog, other_participant_id);
return floater;
}
@@ -1825,24 +1980,25 @@ public:
gIMMgr->updateFloaterSessionID(
temp_session_id,
session_id);
+
+ LLIMModel::getInstance()->updateSessionID(temp_session_id, session_id);
+
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+ if (speaker_mgr)
+ {
+ speaker_mgr->setSpeakers(body);
+ speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
+ }
+
LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
if (floaterp)
{
- floaterp->setSpeakers(body);
-
- //apply updates we've possibly received previously
- floaterp->updateSpeakersList(
- gIMMgr->getPendingAgentListUpdates(session_id));
-
if ( body.has("session_info") )
{
floaterp->processSessionUpdate(body["session_info"]);
}
-
- //aply updates we've possibly received previously
- floaterp->updateSpeakersList(
- gIMMgr->getPendingAgentListUpdates(session_id));
}
+
gIMMgr->clearPendingAgentListUpdates(session_id);
}
else
@@ -1932,15 +2088,15 @@ public:
const LLSD& context,
const LLSD& input) const
{
- LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID());
- if (floaterp)
+ const LLUUID& session_id = input["body"]["session_id"].asUUID();
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+ if (speaker_mgr)
{
- floaterp->updateSpeakersList(
- input["body"]);
+ speaker_mgr->updateSpeakers(input["body"]);
}
else
{
- //we don't have a floater yet..something went wrong
+ //we don't have a speaker manager yet..something went wrong
//we are probably receiving an update here before
//a start or an acceptance of an invitation. Race condition.
gIMMgr->addPendingAgentListUpdates(
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 219af0705d..9a94d01bb2 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -34,6 +34,8 @@
#define LL_LLIMVIEW_H
#include "lldarray.h"
+#include "llfloateractivespeakers.h" //for LLIMSpeakerMgr
+#include "llimpanel.h" //for voice channels
#include "llmodaldialog.h"
#include "llinstantmessage.h"
#include "lluuid.h"
@@ -50,21 +52,40 @@ public:
struct LLIMSession
{
- LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id)
- :mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id) {}
-
+ LLIMSession(const LLUUID& session_id, const std::string& name,
+ const EInstantMessage& type, const LLUUID& other_participant_id);
+ virtual ~LLIMSession();
+
+ LLUUID mSessionID;
std::string mName;
EInstantMessage mType;
LLUUID mOtherParticipantID;
S32 mNumUnread;
std::list<LLSD> mMsgs;
+
+ LLVoiceChannel* mVoiceChannel;
+ LLIMSpeakerMgr* mSpeakers;
};
LLIMModel();
+ //*TODO make it non-static as LLIMMOdel is a singleton (IB)
static std::map<LLUUID, LLIMSession*> sSessionsMap; //mapping session_id to session
+
boost::signals2::signal<void(const LLSD&)> mChangedSignal;
+
+ /**
+ * Find an IM Session corresponding to session_id
+ * Returns NULL if the session does not exist
+ */
+ LLIMSession* findIMSession(const LLUUID& session_id) const;
+
+ /**
+ * Rebind session data to a new session id.
+ */
+ void updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id);
+
boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb );
bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id);
@@ -72,10 +93,42 @@ public:
std::list<LLSD> getMessages(LLUUID session_id, int start_index = 0);
bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text);
bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text);
- //used to get the name of the session, for use as the title
- //currently just the other avatar name
- const std::string& getName(LLUUID session_id);
-
+ //used to get the name of the session, for use as the title
+ //currently just the other avatar name
+ const std::string& getName(const LLUUID& session_id) const;
+
+ /**
+ * Get number of unread messages in a session with session_id
+ * Returns -1 if the session with session_id doesn't exist
+ */
+ const S32 getNumUnread(const LLUUID& session_id) const;
+
+ /**
+ * Get uuid of other participant in a session with session_id
+ * Returns LLUUID::null if the session doesn't exist
+ *
+ * *TODO what to do with other participants in ad-hoc and group chats?
+ */
+ const LLUUID& getOtherParticipantID(const LLUUID& session_id) const;
+
+ /**
+ * Get type of a session specified by session_id
+ * Returns EInstantMessage::IM_COUNT if the session does not exist
+ */
+ EInstantMessage getType(const LLUUID& session_id) const;
+
+ /**
+ * Get voice channel for the session specified by session_id
+ * Returns NULL if the session does not exist
+ */
+ LLVoiceChannel* getVoiceChannel(const LLUUID& session_id) const;
+
+ /**
+ * Get im speaker manager for the session specified by session_id
+ * Returns NULL if the session does not exist
+ */
+ LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const;
+
static void sendLeaveSession(LLUUID session_id, LLUUID other_participant_id);
static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
const std::vector<LLUUID>& ids, EInstantMessage dialog);
diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp
index 2ad83c76b5..0542199fc1 100644
--- a/indra/newview/lllandmarkactions.cpp
+++ b/indra/newview/lllandmarkactions.cpp
@@ -53,10 +53,15 @@
#include "llagentui.h"
-class LLFetchlLandmarkByAgentPos : public LLInventoryCollectFunctor
+class LLFetchlLandmarkByPos : public LLInventoryCollectFunctor
{
-
+private:
+ LLVector3d mPos;
public:
+ LLFetchlLandmarkByPos(const LLVector3d& pos) :
+ mPos(pos)
+ {}
+
/*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if (!item || item->getType() != LLAssetType::AT_LANDMARK)
@@ -69,11 +74,10 @@ public:
LLVector3d landmark_global_pos;
if (!landmark->getGlobalPos(landmark_global_pos))
return false;
- LLVector3d a_pos = gAgent.getPositionGlobal();
//we have to round off each coordinates to compare positions properly
- return llround(a_pos.mdV[VX]) == llround(landmark_global_pos.mdV[VX])
- && llround(a_pos.mdV[VY]) == llround(landmark_global_pos.mdV[VY])
- && llround(a_pos.mdV[VZ]) == llround(landmark_global_pos.mdV[VZ]);
+ return llround(mPos.mdV[VX]) == llround(landmark_global_pos.mdV[VX])
+ && llround(mPos.mdV[VY]) == llround(landmark_global_pos.mdV[VY])
+ && llround(mPos.mdV[VZ]) == llround(landmark_global_pos.mdV[VZ]);
}
};
@@ -147,12 +151,12 @@ bool LLLandmarkActions::landmarkAlreadyExists()
}
-LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
+LLViewerInventoryItem* LLLandmarkActions::findLandmarkForGlobalPos(const LLVector3d &pos)
{
// Determine whether there are landmarks pointing to the current parcel.
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
- LLFetchlLandmarkByAgentPos is_current_pos_landmark;
+ LLFetchlLandmarkByPos is_current_pos_landmark(pos);
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cats,
items,
@@ -167,6 +171,11 @@ LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
return items[0];
}
+LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
+{
+ return findLandmarkForGlobalPos(gAgent.getPositionGlobal());
+}
+
bool LLLandmarkActions::canCreateLandmarkHere()
{
LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h
index ce3ed76090..ab8cc4d6a5 100644
--- a/indra/newview/lllandmarkactions.h
+++ b/indra/newview/lllandmarkactions.h
@@ -53,6 +53,14 @@ public:
static bool landmarkAlreadyExists();
/**
+ * @brief Searches landmark for global position.
+ * @return Returns landmark or NULL.
+ *
+ * *TODO: dzaporozhan: There can be many landmarks for single parcel.
+ */
+ static LLViewerInventoryItem* findLandmarkForGlobalPos(const LLVector3d &pos);
+
+ /**
* @brief Searches landmark for agent global position.
* @return Returns landmark or NULL.
*
@@ -60,6 +68,7 @@ public:
*/
static LLViewerInventoryItem* findLandmarkForAgentPos();
+
/**
* @brief Checks whether agent has rights to create landmark for current parcel.
*/
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 9d14a3fbdc..68dc3854db 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -190,7 +190,6 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
params.max_length_bytes(p.max_chars);
params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2));
params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1));
- params.focus_lost_callback(NULL);
params.handle_edit_keys_directly(true);
params.commit_on_focus_lost(false);
params.follows.flags(FOLLOWS_ALL);
@@ -657,8 +656,9 @@ void LLLocationInputCtrl::changeLocationPresentation()
{
//change location presentation only if user does not select anything and
//human-readable region name is being displayed
- if(mTextEntry && !mTextEntry->hasSelection() &&
- !LLSLURL::isSLURL(mTextEntry->getText()))
+ std::string text = mTextEntry->getText();
+ LLStringUtil::trim(text);
+ if(mTextEntry && !mTextEntry->hasSelection() && !LLSLURL::isSLURL(text))
{
//needs unescaped one
mTextEntry->setText(LLAgentUI::buildSLURL(false));
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 09a7edaa43..b996c15a7d 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -36,7 +36,6 @@
#include "llmediactrl.h"
// viewer includes
-#include "llfloaterhtml.h"
#include "llfloaterworldmap.h"
#include "lluictrlfactory.h"
#include "llurldispatcher.h"
@@ -44,6 +43,7 @@
#include "llviewborder.h"
#include "llviewercontrol.h"
#include "llviewermedia.h"
+#include "llviewertexture.h"
#include "llviewerwindow.h"
#include "llnotifications.h"
#include "llweb.h"
@@ -64,6 +64,9 @@ LLMediaCtrl::Params::Params()
border_visible("border_visible", true),
ignore_ui_scale("ignore_ui_scale", true),
hide_loading("hide_loading", false),
+ decouple_texture_size("decouple_texture_size", false),
+ texture_width("texture_width", 1024),
+ texture_height("texture_height", 1024),
caret_color("caret_color")
{}
@@ -83,10 +86,12 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
mMediaSource( 0 ),
mTakeFocusOnClick( true ),
mCurrentNavUrl( "" ),
- mLastSetCursor( UI_CURSOR_ARROW ),
mStretchToFill( true ),
mMaintainAspectRatio ( true ),
- mHideLoading (false)
+ mHideLoading (false),
+ mDecoupleTextureSize ( false ),
+ mTextureWidth ( 1024 ),
+ mTextureHeight ( 1024 )
{
{
LLColor4 color = p.caret_color().get();
@@ -100,24 +105,29 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
setBorderVisible(p.border_visible());
mHideLoading = p.hide_loading();
+
+ setDecoupleTextureSize(p.decouple_texture_size());
+
+ setTextureSize(p.texture_width(), p.texture_height());
- S32 screen_width = mIgnoreUIScale ?
- llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth();
- S32 screen_height = mIgnoreUIScale ?
- llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight();
+ if(!getDecoupleTextureSize())
+ {
+ S32 screen_width = mIgnoreUIScale ?
+ llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth();
+ S32 screen_height = mIgnoreUIScale ?
+ llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight();
+
+ setTextureSize(screen_width, screen_height);
+ }
mMediaTextureID.generate();
- mMediaSource = LLViewerMedia::newMediaImpl(mHomePageUrl, mMediaTextureID, screen_width, screen_height, false, false, "text/html");
- if ( !mMediaSource )
+
+ // 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())
{
- llwarns << "media source create failed " << llendl;
- // return;
+ navigateHome();
}
-
- mMediaSource->setVisible( getVisible() );
-
- mMediaSource->addObserver( this );
-
+
// FIXME: How do we create a bevel now?
// LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 );
// mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN );
@@ -180,9 +190,10 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
convertInputCoords(x, y);
if (mMediaSource)
+ {
mMediaSource->mouseMove(x, y);
-
- gViewerWindow->setCursor(mLastSetCursor);
+ gViewerWindow->setCursor(mMediaSource->getLastSetCursor());
+ }
return TRUE;
}
@@ -390,19 +401,19 @@ void LLMediaCtrl::onVisibilityChange ( const LLSD& new_visibility )
//
void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
{
- S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width;
- S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height;
-
-// llinfos << "reshape called with width = " << width << ", height = " << height << llendl;
-
- // when floater is minimized, these sizes are negative
- if ( screen_height > 0 && screen_width > 0 )
+ if(!getDecoupleTextureSize())
{
- mMediaSource->setSize(screen_width, screen_height);
- mForceUpdate = true;
- }
+ S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width;
+ S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height;
- LLPanel::reshape( width, height, called_from_parent );
+ // when floater is minimized, these sizes are negative
+ if ( screen_height > 0 && screen_width > 0 )
+ {
+ setTextureSize(screen_width, screen_height);
+ }
+ }
+
+ LLUICtrl::reshape( width, height, called_from_parent );
}
////////////////////////////////////////////////////////////////////////////////
@@ -476,9 +487,10 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type)
return;
}
- if (mMediaSource)
+ if (ensureMediaSourceExists())
{
mCurrentNavUrl = url_in;
+ mMediaSource->setSize(mTextureWidth, mTextureHeight);
mMediaSource->navigateTo(url_in, mime_type, mime_type.empty());
}
}
@@ -514,9 +526,10 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str
return;
}
}
- if (mMediaSource)
+ if (ensureMediaSourceExists())
{
mCurrentNavUrl = expanded_filename;
+ mMediaSource->setSize(mTextureWidth, mTextureHeight);
mMediaSource->navigateTo(expanded_filename, "text/html", false);
}
@@ -526,11 +539,11 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str
//
void LLMediaCtrl::navigateHome()
{
- if( mHomePageUrl.length() )
+ if (ensureMediaSourceExists())
{
- if (mMediaSource)
- mMediaSource->navigateTo(mHomePageUrl);
- };
+ mMediaSource->setSize(mTextureWidth, mTextureHeight);
+ mMediaSource->navigateHome();
+ }
}
////////////////////////////////////////////////////////////////////////////////
@@ -538,6 +551,10 @@ void LLMediaCtrl::navigateHome()
void LLMediaCtrl::setHomePageUrl( const std::string urlIn )
{
mHomePageUrl = urlIn;
+ if (mMediaSource)
+ {
+ mMediaSource->setHomeURL(mHomePageUrl);
+ }
}
////////////////////////////////////////////////////////////////////////////////
@@ -547,6 +564,21 @@ bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned i
//NOOP
return false;
}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::setTextureSize(S32 width, S32 height)
+{
+ mTextureWidth = width;
+ mTextureHeight = height;
+
+ if(mMediaSource)
+ {
+ mMediaSource->setSize(mTextureWidth, mTextureHeight);
+ mForceUpdate = true;
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
//
std::string LLMediaCtrl::getHomePageUrl()
@@ -556,6 +588,38 @@ std::string LLMediaCtrl::getHomePageUrl()
////////////////////////////////////////////////////////////////////////////////
//
+bool LLMediaCtrl::ensureMediaSourceExists()
+{
+ if(mMediaSource.isNull())
+ {
+ // If we don't already have a media source, try to create one.
+ mMediaSource = LLViewerMedia::newMediaImpl(mMediaTextureID, mTextureWidth, mTextureHeight);
+ if ( mMediaSource )
+ {
+ mMediaSource->setUsedInUI(true);
+ mMediaSource->setHomeURL(mHomePageUrl);
+ mMediaSource->setVisible( getVisible() );
+ mMediaSource->addObserver( this );
+ }
+ else
+ {
+ llwarns << "media source create failed " << llendl;
+ // return;
+ }
+ }
+
+ return !mMediaSource.isNull();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::unloadMediaSource()
+{
+ mMediaSource = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
LLPluginClassMedia* LLMediaCtrl::getMediaPlugin()
{
return mMediaSource.isNull() ? NULL : mMediaSource->getMediaPlugin();
@@ -575,13 +639,17 @@ void LLMediaCtrl::draw()
{
return;
}
+
+ if(!media_plugin || (!media_plugin->textureValid()))
+ {
+ // Don't try to draw without a valid texture
+ return;
+ }
LLViewerMediaTexture* media_texture = LLViewerTextureManager::findMediaTexture(mMediaTextureID);
if (!media_texture )
- {
return;
- }
if ( gRestoreGL == 1 )
{
@@ -659,7 +727,7 @@ void LLMediaCtrl::draw()
width = llmin(media_plugin->getWidth(), r.getWidth());
height = llmin(media_plugin->getHeight(), r.getHeight());
}
-
+
x_offset = (r.getWidth() - width) / 2;
y_offset = (r.getHeight() - height) / 2;
@@ -775,24 +843,9 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
case MEDIA_EVENT_CURSOR_CHANGED:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL;
-
- std::string cursor = self->getCursorName();
-
- if(cursor == "arrow")
- mLastSetCursor = UI_CURSOR_ARROW;
- else if(cursor == "ibeam")
- mLastSetCursor = UI_CURSOR_IBEAM;
- else if(cursor == "splith")
- mLastSetCursor = UI_CURSOR_SIZEWE;
- else if(cursor == "splitv")
- mLastSetCursor = UI_CURSOR_SIZENS;
- else if(cursor == "hand")
- mLastSetCursor = UI_CURSOR_HAND;
- else // for anything else, default to the arrow
- mLastSetCursor = UI_CURSOR_ARROW;
- };
+ }
break;
-
+
case MEDIA_EVENT_NAVIGATE_BEGIN:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL;
@@ -898,15 +951,7 @@ void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self )
if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
{
- // If we spawn a new LLFloaterHTML, assume we want it to
- // follow this LLMediaCtrl's trust for whether or
- // not to open secondlife:///app/ links. JC.
-// const bool open_links_externally = false;
-// LLFloaterHtml::getInstance()->show(
-// event_in.mStringPayload,
-// "Second Life Browser",
-// open_links_externally,
-// mTrusted);
+ llwarns << "Dead, unimplemented path that we used to send to the built-in browser long ago." << llendl;
}
}
}
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index a19b3ad67b..5ea03f1e6c 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -37,7 +37,6 @@
#include "lluictrl.h"
#include "llframetimer.h"
-#include "lldynamictexture.h"
class LLViewBorder;
class LLUICtrlFactory;
@@ -50,7 +49,6 @@ class LLMediaCtrl :
public LLViewerMediaEventEmitter
{
LOG_CLASS(LLMediaCtrl);
-
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
@@ -58,7 +56,11 @@ public:
Optional<bool> border_visible,
ignore_ui_scale,
- hide_loading;
+ hide_loading,
+ decouple_texture_size;
+
+ Optional<S32> texture_width,
+ texture_height;
Optional<LLUIColor> caret_color;
@@ -127,9 +129,17 @@ public:
void setForceUpdate(bool force_update) { mForceUpdate = force_update; }
bool getForceUpdate() { return mForceUpdate; }
+ bool ensureMediaSourceExists();
+ void unloadMediaSource();
+
LLPluginClassMedia* getMediaPlugin();
bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue );
+
+ void setDecoupleTextureSize(bool decouple) { mDecoupleTextureSize = decouple; }
+ bool getDecoupleTextureSize() { return mDecoupleTextureSize; }
+
+ void setTextureSize(S32 width, S32 height);
// over-rides
@@ -173,10 +183,12 @@ public:
bool mAlwaysRefresh;
viewer_media_t mMediaSource;
bool mTakeFocusOnClick;
- ECursorType mLastSetCursor;
bool mStretchToFill;
bool mMaintainAspectRatio;
bool mHideLoading;
+ bool mDecoupleTextureSize;
+ S32 mTextureWidth;
+ S32 mTextureHeight;
};
#endif // LL_LLMediaCtrl_H
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index b1db51dd26..19fee20740 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -317,6 +317,7 @@ void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
void LLNavigationBar::onLocationSelection()
{
std::string typed_location = mCmbLocation->getSimple();
+ LLStringUtil::trim(typed_location);
// Will not teleport to empty location.
if (typed_location.empty())
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index b53bb586f3..8430937933 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -65,6 +65,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key) :
mChatCaptionPanel(NULL),
mChatHistoryEditor(NULL)
{
+ m_isDirty = false;
}
LLNearbyChat::~LLNearbyChat()
@@ -181,7 +182,7 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat)
return text_color;
}
-void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color)
+void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& color)
{
std::string line = chat.mText;
@@ -194,25 +195,28 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons
bool prepend_newline = true;
if (gSavedSettings.getBOOL("ChatShowTimestamps"))
{
- edit->appendTime(prepend_newline);
+ mChatHistoryEditor->appendTime(prepend_newline);
prepend_newline = false;
}
// If the msg is from an agent (not yourself though),
// extract out the sender name and replace it with the hotlinked name.
+
+ std::string str_URL = chat.mURL;
+
if (chat.mSourceType == CHAT_SOURCE_AGENT &&
chat.mFromID != LLUUID::null)
{
- chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
+ str_URL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
}
// If the chat line has an associated url, link it up to the name.
- if (!chat.mURL.empty()
+ if (!str_URL.empty()
&& (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0))
{
std::string start_line = line.substr(0, chat.mFromName.length() + 1);
line = line.substr(chat.mFromName.length() + 1);
- edit->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,chat.mURL));
+ mChatHistoryEditor->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,str_URL));
prepend_newline = false;
}
@@ -225,11 +229,9 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons
else if (2 == font_size)
font_name = "sansserifbig";
- edit->appendColoredText(line, false, prepend_newline, color, font_name);
+ mChatHistoryEditor->appendColoredText(line, false, prepend_newline, color, font_name);
}
-
-
void LLNearbyChat::addMessage(const LLChat& chat)
{
LLColor4 color = nearbychat_get_text_color(chat);
@@ -254,7 +256,7 @@ void LLNearbyChat::addMessage(const LLChat& chat)
mChatHistoryEditor->setParseHighlights(TRUE);
if (!chat.mMuted)
- nearbychat_add_timestamped_line(mChatHistoryEditor, chat, color);
+ add_timestamped_line(chat, color);
}
void LLNearbyChat::onNearbySpeakers()
@@ -482,9 +484,16 @@ BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask)
void LLNearbyChat::onOpen(const LLSD& key )
{
- LLNotificationsUI::LLScreenChannel* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+ LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
if(chat_channel)
{
chat_channel->removeToastsFromChannel();
}
}
+
+void LLNearbyChat::draw ()
+{
+ LLFloater::draw();
+}
+
+
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index efa2e479e6..599e6b6859 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -76,7 +76,10 @@ public:
virtual void onOpen (const LLSD& key);
+ virtual void draw ();
+
private:
+ void add_timestamped_line(const LLChat& chat, const LLColor4& color);
void pinn_panel();
void float_panel();
@@ -86,10 +89,11 @@ private:
S32 mStart_X;
S32 mStart_Y;
- //LLResizeBar* mResizeBar[RESIZE_BAR_COUNT];
LLHandle<LLView> mPopupMenuHandle;
LLPanel* mChatCaptionPanel;
LLViewerTextEditor* mChatHistoryEditor;
+
+ bool m_isDirty;
};
#endif
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index cec4b9f7c7..1d8789fde0 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -190,7 +190,7 @@ BOOL LLNearbyChatBar::postBuild()
mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));
mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
- mChatBox->setFocusLostCallback(&onChatBoxFocusLost, this);
+ mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
mChatBox->setIgnoreArrowKeys(TRUE);
mChatBox->setCommitOnFocusLost( FALSE );
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 7eb5d91e53..eb42e83994 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -41,30 +41,227 @@
#include "llviewercontrol.h"
#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
+#include "llviewerwindow.h"//for screen channel position
//add LLNearbyChatHandler to LLNotificationsUI namespace
-namespace LLNotificationsUI{
+using namespace LLNotificationsUI;
+//-----------------------------------------------------------------------------------------------
+//LLNearbyChatScreenChannel
+//-----------------------------------------------------------------------------------------------
+LLToastPanelBase* createToastPanel()
+{
+ LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance();
+ static S32 chat_item_width = 304;
+ item->setWidth(chat_item_width);
+ return item;
+}
+
+
+class LLNearbyChatScreenChannel: public LLScreenChannelBase
+{
+public:
+ LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id) { mActiveMessages = 0;};
+ void init (S32 channel_left, S32 channel_right);
+
+ void addNotification (LLSD& notification);
+ void arrangeToasts ();
+ void showToastsBottom ();
+
+ typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t;
+ void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
+
+ void onToastDestroyed (LLToast* toast);
+ void onToastFade (LLToast* toast);
+
+ // hide all toasts from screen, but not remove them from a channel
+ virtual void hideToastsFromScreen()
+ {
+ };
+ // removes all toasts from a channel
+ virtual void removeToastsFromChannel()
+ {
+ for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+ {
+ LLToast* toast = (*it);
+ toast->setVisible(FALSE);
+ toast->stopTimer();
+ m_toast_pool.push_back(toast);
+
+ }
+ m_active_toasts.clear();
+ };
+
+protected:
+ void createOverflowToast(S32 bottom, F32 timer);
+
+ create_toast_panel_callback_t m_create_toast_panel_callback_t;
+
+ bool createPoolToast();
+
+ std::vector<LLToast*> m_active_toasts;
+ std::list<LLToast*> m_toast_pool;
+
+ S32 mActiveMessages;
+};
+
+void LLNearbyChatScreenChannel::init(S32 channel_left, S32 channel_right)
+{
+ S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
+ S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom;
+ setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
+ setVisible(TRUE);
+}
+
+
+void LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
+{
+ //we don't need overflow toast in nearby chat
+}
+
+void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast)
+{
+}
+
+void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)
+{
+ //fade mean we put toast to toast pool
+ if(!toast)
+ return;
+ m_toast_pool.push_back(toast);
+
+ std::vector<LLToast*>::iterator pos = std::find(m_active_toasts.begin(),m_active_toasts.end(),toast);
+ if(pos!=m_active_toasts.end())
+ m_active_toasts.erase(pos);
+
+ arrangeToasts();
+}
+
+
+bool LLNearbyChatScreenChannel::createPoolToast()
+{
+ LLToastPanelBase* panel= m_create_toast_panel_callback_t();
+ if(!panel)
+ return false;
+
+ LLToast::Params p;
+ p.panel = panel;
+
+ LLToast* toast = new LLToast(p);
+
+
+ toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1));
+ toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1));
+
+ m_toast_pool.push_back(toast);
+ return true;
+}
+
+void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
+{
+ //look in pool. if there is any message
+
+
+ if(m_toast_pool.empty())
+ {
+ //"pool" is empty - create one more panel
+ if(!createPoolToast())//created toast will go to pool. so next call will find it
+ return;
+ addNotification(notification);
+ return;
+ }
+
+ //take 1st element from pool, (re)initialize it, put it in active toasts
+
+ LLToast* toast = m_toast_pool.back();
+
+ m_toast_pool.pop_back();
+
+
+ LLToastPanelBase* panel = dynamic_cast<LLToastPanelBase*>(toast->getPanel());
+ if(!panel)
+ return;
+ panel->init(notification);
+
+ toast->reshapeToPanel();
+ toast->resetTimer();
+
+ m_active_toasts.insert(m_active_toasts.begin(),toast);
+
+ arrangeToasts();
+}
+
+void LLNearbyChatScreenChannel::arrangeToasts()
+{
+ if(m_active_toasts.size() == 0 || mIsHovering)
+ return;
+
+ hideToastsFromScreen();
+
+ showToastsBottom();
+}
+
+void LLNearbyChatScreenChannel::showToastsBottom()
+{
+ LLRect rect = getRect();
+
+ LLRect toast_rect;
+ S32 bottom = getRect().mBottom;
+
+ for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+ {
+ LLToast* toast = (*it);
+ toast_rect = toast->getRect();
+ toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());
+
+ toast->setRect(toast_rect);
+
+ if(toast->getRect().mTop > getRect().getHeight())
+ {
+ while(it!=m_active_toasts.end())
+ {
+ (*it)->setVisible(FALSE);
+ (*it)->stopTimer();
+ m_toast_pool.push_back(*it);
+ it=m_active_toasts.erase(it);
+ }
+ break;
+ }
+ toast->setVisible(TRUE);
+ bottom = toast->getRect().mTop;
+ }
+}
+
+
+//-----------------------------------------------------------------------------------------------
+//LLNearbyChatHandler
+//-----------------------------------------------------------------------------------------------
LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
{
mType = type;
- LLChannelManager::Params p;
- p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
// Getting a Channel for our notifications
- mChannel = LLChannelManager::getInstance()->getChannel(p);
+ LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+
+ LLNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
+
+ channel->setCreatePanelCallback(callback);
+
+ mChannel = LLChannelManager::getInstance()->addChannel(channel);
mChannel->setOverflowFormatString("You have %d unread nearby chat messages");
}
+
LLNearbyChatHandler::~LLNearbyChatHandler()
{
}
+
void LLNearbyChatHandler::initChannel()
{
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
S32 channel_right_bound = nearby_chat->getRect().mRight;
- S32 channel_width = nearby_chat->getRect().mRight - 16; //HACK: 16 - ?
+ S32 channel_width = nearby_chat->getRect().mRight;
mChannel->init(channel_right_bound - channel_width, channel_right_bound);
}
@@ -77,41 +274,42 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
if(chat_msg.mText.empty())
return;//don't process empty messages
-
+
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
nearby_chat->addMessage(chat_msg);
if(nearby_chat->getVisible())
return;//no need in toast if chat is visible
-
+
// arrange a channel on a screen
if(!mChannel->getVisible())
{
initChannel();
}
-
+
LLUUID id;
id.generate();
- LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
-
- item->setMessage(chat_msg);
- //static S32 chat_item_width = nearby_chat->getRect().getWidth() - 16;
- static S32 chat_item_width = 304;
- item->setWidth(chat_item_width);
- item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
+ LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel);
- item->setVisible(true);
- LLToast::Params p;
- p.notif_id = id;
- p.panel = item;
- p.on_delete_toast = boost::bind(&LLNearbyChatHandler::onDeleteToast, this, _1);
- mChannel->addToast(p);
+ if(channel)
+ {
+ LLSD notification;
+ notification["id"] = id;
+ notification["message"] = chat_msg.mText;
+ notification["from"] = chat_msg.mFromName;
+ notification["from_id"] = chat_msg.mFromID;
+ notification["time"] = chat_msg.mTime;
+ notification["source"] = (S32)chat_msg.mSourceType;
+
+ channel->addNotification(notification);
+ }
+
}
void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
{
}
-}
+
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 3893eaa0d4..1be03cef0b 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -55,7 +55,7 @@ LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsMo
// Getting a Channel for our notifications
mChannel = LLChannelManager::getInstance()->getChannel(p);
- mChannel->setShowToasts(true);
+ mChannel->setCanStoreToasts(false);
}
//--------------------------------------------------------------------------
@@ -100,16 +100,23 @@ bool LLAlertHandler::processNotification(const LLSD& notify)
p.can_fade = false;
p.is_modal = mIsModal;
p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
- mChannel->addToast(p);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
}
else if (notify["sigtype"].asString() == "change")
{
LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
- mChannel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
}
else
{
- mChannel->killToastByNotificationID(notification->getID());
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->killToastByNotificationID(notification->getID());
}
return true;
}
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index c488d37ea5..ffa92b543c 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -89,7 +89,10 @@ bool LLGroupHandler::processNotification(const LLSD& notify)
p.notification = notification;
p.panel = notify_box;
p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
- mChannel->addToast(p);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
// send a signal to the counter manager
mNewNotificationSignal();
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 90ff5fbaac..cd4e640ec4 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -104,8 +104,8 @@ protected:
// at the moment, when a handlers creates a channel.
virtual void initChannel()=0;
- LLScreenChannel* mChannel;
- e_notification_type mType;
+ LLScreenChannelBase* mChannel;
+ e_notification_type mType;
};
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 72855ac0fd..070af432d6 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -48,7 +48,11 @@ LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
// Getting a Channel for our notifications
mChannel = LLChannelManager::getInstance()->createNotificationChannel();
mChannel->setControlHovering(true);
- mChannel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+
}
//--------------------------------------------------------------------------
@@ -92,7 +96,10 @@ bool LLScriptHandler::processNotification(const LLSD& notify)
p.notification = notification;
p.panel = notify_box;
p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
- mChannel->addToast(p);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
// send a signal to the counter manager
mNewNotificationSignal();
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index 740acb6365..5186a93569 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -93,8 +93,9 @@ bool LLTipHandler::processNotification(const LLSD& notify)
p.is_tip = true;
p.can_be_stored = false;
- mChannel->addToast(p);
-
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
}
else if (notify["sigtype"].asString() == "delete")
{
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 6e1dc6940e..d9cdf2e04f 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -129,7 +129,7 @@ void LLOutputMonitorCtrl::draw()
const F32 LEVEL_1 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL * 2.f / 3.f;
const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
- if (mIsParentVisible && getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull())
+ if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull())
{
setPower(gVoiceClient->getCurrentPower(mSpeakerId));
setIsTalking(gVoiceClient->getIsSpeaking(mSpeakerId));
@@ -220,12 +220,6 @@ void LLOutputMonitorCtrl::draw()
gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);
}
-void LLOutputMonitorCtrl::handleVisibilityChange(BOOL new_visibility)
-{
- mIsParentVisible = new_visibility;
- LLView::handleVisibilityChange(new_visibility);
-}
-
void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id)
{
if (speaker_id.isNull()) return;
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 0e213c4326..7a7b8bc3a1 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -72,8 +72,6 @@ public:
// llview overrides
virtual void draw();
- void handleVisibilityChange(BOOL new_visibility);
-
void setPower(F32 val);
F32 getPower(F32 val) const { return mPower; }
@@ -104,8 +102,6 @@ private:
F32 mPower;
bool mIsMuted;
bool mIsTalking;
- /** Stores flag whether parent is visible. If not it will not update indicator*/
- bool mIsParentVisible;
LLPointer<LLUIImage> mImageMute;
LLPointer<LLUIImage> mImageOff;
LLPointer<LLUIImage> mImageOn;
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 649697e091..7ccff73080 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -313,7 +313,7 @@ void LLPanelProfileTab::scrollToTop()
{
LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
if (scrollContainer)
- scrollContainer->goToTop();
+ scrollContainer->goToTop();
}
//////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index ee5d265220..7eaee92778 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -238,13 +238,13 @@ BOOL LLPanelClassified::postBuild()
mNameEditor = getChild<LLLineEditor>("given_name_editor");
mNameEditor->setMaxTextLength(DB_PARCEL_NAME_LEN);
mNameEditor->setCommitOnFocusLost(TRUE);
- mNameEditor->setFocusReceivedCallback(focusReceived, this);
+ mNameEditor->setFocusReceivedCallback(boost::bind(focusReceived, _1, this));
mNameEditor->setCommitCallback(onCommitAny, this);
mNameEditor->setPrevalidate( LLLineEditor::prevalidateASCII );
mDescEditor = getChild<LLTextEditor>("desc_editor");
mDescEditor->setCommitOnFocusLost(TRUE);
- mDescEditor->setFocusReceivedCallback(focusReceived, this);
+ mDescEditor->setFocusReceivedCallback(boost::bind(focusReceived, _1, this));
mDescEditor->setCommitCallback(onCommitAny, this);
mLocationEditor = getChild<LLLineEditor>("location_editor");
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 5da646497b..ea528a1df8 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -72,6 +72,13 @@
//
// Globals
//
+const char* LLPanelContents::TENTATIVE_SUFFIX = "_tentative";
+const char* LLPanelContents::PERMS_OWNER_INTERACT_KEY = "perms_owner_interact";
+const char* LLPanelContents::PERMS_OWNER_CONTROL_KEY = "perms_owner_control";
+const char* LLPanelContents::PERMS_GROUP_INTERACT_KEY = "perms_group_interact";
+const char* LLPanelContents::PERMS_GROUP_CONTROL_KEY = "perms_group_control";
+const char* LLPanelContents::PERMS_ANYONE_INTERACT_KEY = "perms_anyone_interact";
+const char* LLPanelContents::PERMS_ANYONE_CONTROL_KEY = "perms_anyone_control";
BOOL LLPanelContents::postBuild()
{
@@ -83,7 +90,7 @@ BOOL LLPanelContents::postBuild()
childSetAction("button permissions",&LLPanelContents::onClickPermissions, this);
mPanelInventory = getChild<LLPanelInventory>("contents_inventory");
-
+
return TRUE;
}
@@ -112,7 +119,7 @@ void LLPanelContents::getState(LLViewerObject *objectp )
LLSelectMgr::getInstance()->selectGetGroup(group_id); // sets group_id as a side effect SL-23488
// BUG? Check for all objects being editable?
- BOOL editable = gAgent.isGodlike()
+ bool editable = gAgent.isGodlike()
|| (objectp->permModify()
&& ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488
BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
@@ -123,8 +130,8 @@ void LLPanelContents::getState(LLViewerObject *objectp )
all_volume &&
((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
|| (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)));
-}
+}
void LLPanelContents::refresh()
{
@@ -135,7 +142,7 @@ void LLPanelContents::refresh()
if (mPanelInventory)
{
mPanelInventory->refresh();
- }
+ }
}
diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h
index de1914bff9..bab980b524 100644
--- a/indra/newview/llpanelcontents.h
+++ b/indra/newview/llpanelcontents.h
@@ -51,11 +51,23 @@ public:
void refresh();
- static void onClickNewScript( void* userdata);
- static void onClickPermissions( void* userdata);
+
+ static void onClickNewScript(void*);
+ static void onClickPermissions(void*);
+
+ // Key suffix for "tentative" fields
+ static const char* TENTATIVE_SUFFIX;
+
+ // These aren't fields in LLMediaEntry, so we have to define them ourselves for checkbox control
+ static const char* PERMS_OWNER_INTERACT_KEY;
+ static const char* PERMS_OWNER_CONTROL_KEY;
+ static const char* PERMS_GROUP_INTERACT_KEY;
+ static const char* PERMS_GROUP_CONTROL_KEY;
+ static const char* PERMS_ANYONE_INTERACT_KEY;
+ static const char* PERMS_ANYONE_CONTROL_KEY;
protected:
- void getState(LLViewerObject *object);
+ void getState(LLViewerObject *object);
public:
LLPanelInventory* mPanelInventory;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 08a50d4b6e..c61b987b1c 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -49,6 +49,7 @@
#include "llcombobox.h"
#include "lldrawpoolbump.h"
#include "lllineeditor.h"
+#include "llmediaentry.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llspinctrl.h"
@@ -61,6 +62,7 @@
#include "llviewermedia.h"
#include "llviewerobject.h"
#include "llviewerstats.h"
+#include "llvovolume.h"
#include "lluictrlfactory.h"
#include "llpluginclassmedia.h"
@@ -70,6 +72,18 @@
BOOL LLPanelFace::postBuild()
{
+ childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
+ childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
+ childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
+ childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
+ childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
+ childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
+ childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
+ childSetAction("button apply",&LLPanelFace::onClickApply,this);
+ childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
+ childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
+ childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
+
LLRect rect = this->getRect();
LLTextureCtrl* mTextureCtrl;
LLColorSwatchCtrl* mColorSwatch;
@@ -91,7 +105,7 @@ BOOL LLPanelFace::postBuild()
mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) );
mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
- mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, _2));
+ mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
mTextureCtrl->setFollowsTop();
mTextureCtrl->setFollowsLeft();
// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
@@ -161,17 +175,6 @@ BOOL LLPanelFace::postBuild()
mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
}
- childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
- childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
- childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
- childSetAction("button apply",&onClickApply,this);
- childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
- childSetAction("button align",onClickAutoFix,this);
clearCtrls();
@@ -382,10 +385,8 @@ void LLPanelFace::getState()
BOOL editable = objectp->permModify();
// only turn on auto-adjust button if there is a media renderer and the media is loaded
- childSetEnabled("textbox autofix",FALSE);
- //mLabelTexAutoFix->setEnabled ( FALSE );
- childSetEnabled("button align",FALSE);
- //mBtnAutoFix->setEnabled ( FALSE );
+ childSetEnabled("textbox autofix", editable);
+ childSetEnabled("button align", editable);
//if ( LLMediaEngine::getInstance()->getMediaRenderer () )
// if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () )
@@ -785,6 +786,9 @@ void LLPanelFace::getState()
childSetEnabled("button align",FALSE);
childSetEnabled("button apply",FALSE);
+ childSetEnabled("has media", FALSE);
+ childSetEnabled("media info set", FALSE);
+
}
}
@@ -862,7 +866,7 @@ void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
}
// static
-BOOL LLPanelFace::onDragTexture(LLInventoryItem* item)
+BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
{
BOOL accept = TRUE;
for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
@@ -917,15 +921,25 @@ void LLPanelFace::onClickApply(void* userdata)
LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
}
-// commit the fit media texture to prim button
-
struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor
{
virtual bool apply(LLViewerObject* object, S32 te)
{
- // TODO: the media impl pointer should actually be stored by the texture
- viewer_media_t pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(object->getTE ( te )->getID());
- // only do this if it's a media texture
+ viewer_media_t pMediaImpl;
+
+ const LLTextureEntry* tep = object->getTE(te);
+ const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
+ if ( mep )
+ {
+ pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
+ }
+
+ if ( pMediaImpl.isNull())
+ {
+ // If we didn't find face media for this face, check whether this face is showing parcel media.
+ pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
+ }
+
if ( pMediaImpl.notNull())
{
LLPluginClassMedia *media = pMediaImpl->getMediaPlugin();
@@ -957,3 +971,14 @@ void LLPanelFace::onClickAutoFix(void* userdata)
LLPanelFaceSendFunctor sendfunc;
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
}
+
+
+
+// TODO: I don't know who put these in or what these are for???
+void LLPanelFace::setMediaURL(const std::string& url)
+{
+}
+void LLPanelFace::setMediaType(const std::string& mime_type)
+{
+}
+
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 9600129696..6a8704ce14 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -47,6 +47,7 @@ class LLTextBox;
class LLTextureCtrl;
class LLUICtrl;
class LLViewerObject;
+class LLFloater;
class LLPanelFace : public LLPanel
{
@@ -56,6 +57,8 @@ public:
virtual ~LLPanelFace();
void refresh();
+ void setMediaURL(const std::string& url);
+ void setMediaType(const std::string& mime_type);
protected:
void getState();
@@ -69,9 +72,10 @@ protected:
void sendShiny(); // applies and sends shininess
void sendFullbright(); // applies and sends full bright
void sendGlow();
+ void sendMedia();
// this function is to return TRUE if the drag should succeed.
- static BOOL onDragTexture(LLInventoryItem* item);
+ static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
void onCommitTexture(const LLSD& data);
void onCancelTexture(const LLSD& data);
@@ -87,10 +91,11 @@ protected:
static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
static void onCommitFullbright( LLUICtrl* ctrl, void* userdata);
static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
-
+
static void onClickApply(void*);
static void onClickAutoFix(void*);
static F32 valueGlow(LLViewerObject* object, S32 face);
+
};
#endif
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 490c845c94..2b584910a3 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -195,7 +195,7 @@ BOOL LLPanelGroup::postBuild()
if(panel_land) mTabs.push_back(panel_land);
if(panel_general)
- panel_general->setupCtrls(this);
+ panel_general->setupCtrls(this);
return TRUE;
}
@@ -206,8 +206,8 @@ void LLPanelGroup::reposButton(const std::string& name)
if(!button)
return;
LLRect btn_rect = button->getRect();
- btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
- button->setRect(btn_rect);
+ btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
+ button->setRect(btn_rect);
}
void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent )
@@ -235,7 +235,14 @@ void LLPanelGroup::onBtnCreate()
if(!panel_general)
return;
std::string apply_mesg;
- panel_general->apply(apply_mesg);//yes yes you need to call apply to create...
+ if(panel_general->apply(apply_mesg))//yes yes you need to call apply to create...
+ return;
+ if ( !apply_mesg.empty() )
+ {
+ LLSD args;
+ args["MESSAGE"] = apply_mesg;
+ LLNotifications::instance().add("GenericAlert", args);
+ }
}
void LLPanelGroup::onBtnRefresh(void* user_data)
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index d63fd141b0..2e1d971995 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -99,8 +99,8 @@ BOOL LLPanelGroupGeneral::postBuild()
if(mEditCharter)
{
mEditCharter->setCommitCallback(onCommitAny, this);
- mEditCharter->setFocusReceivedCallback(onFocusEdit, this);
- mEditCharter->setFocusChangedCallback(onFocusEdit, this);
+ mEditCharter->setFocusReceivedCallback(boost::bind(onFocusEdit, _1, this));
+ mEditCharter->setFocusChangedCallback(boost::bind(onFocusEdit, _1, this));
}
@@ -835,6 +835,7 @@ void LLPanelGroupGeneral::reset()
{
std::string empty_str = "";
mEditCharter->setText(empty_str);
+ mGroupNameEditor->setText(empty_str);
}
{
@@ -850,6 +851,7 @@ void LLPanelGroupGeneral::reset()
{
mComboMature->setEnabled(true);
mComboMature->setVisible( !gAgent.isTeen() );
+ mComboMature->selectFirstItem();
}
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 378a09e315..99bb760b61 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1730,7 +1730,7 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
mRoleDescription->setCommitOnFocusLost(TRUE);
mRoleDescription->setCommitCallback(onDescriptionCommit, this);
- mRoleDescription->setFocusReceivedCallback(onDescriptionFocus, this);
+ mRoleDescription->setFocusReceivedCallback(boost::bind(onDescriptionFocus, _1, this));
setFooterEnabled(FALSE);
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index 994bf7e3f9..42ad9820a8 100644
--- a/indra/newview/llpanellandmedia.cpp
+++ b/indra/newview/llpanellandmedia.cpp
@@ -122,9 +122,6 @@ BOOL LLPanelLandMedia::postBuild()
mSetURLButton = getChild<LLButton>("set_media_url");
childSetAction("set_media_url", onSetBtn, this);
- mResetURLButton = getChild<LLButton>("reset_media_url");
- childSetAction("reset_media_url", onResetBtn, this);
-
return TRUE;
}
@@ -215,13 +212,7 @@ void LLPanelLandMedia::refresh()
mMediaTextureCtrl->setEnabled( can_change_media );
mSetURLButton->setEnabled( can_change_media );
- mResetURLButton->setEnabled( can_change_media );
- LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mURLEntryFloater.get();
- if (floater_url_entry)
- {
- floater_url_entry->updateFromLandMediaPanel();
- }
}
}
@@ -341,7 +332,7 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl*, void *userdata)
void LLPanelLandMedia::onSetBtn(void *userdata)
{
LLPanelLandMedia *self = (LLPanelLandMedia *)userdata;
- self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle() );
+ self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle(), self->getMediaURL() );
LLFloater* parent_floater = gFloaterView->getParentFloater(self);
if (parent_floater)
{
diff --git a/indra/newview/llpanellandmedia.h b/indra/newview/llpanellandmedia.h
index 5ad1f9758d..3deea29d17 100644
--- a/indra/newview/llpanellandmedia.h
+++ b/indra/newview/llpanellandmedia.h
@@ -63,8 +63,6 @@ private:
LLLineEditor* mMediaDescEdit;
LLComboBox* mMediaTypeCombo;
LLButton* mSetURLButton;
- LLButton* mResetURLButton;
- LLSpinCtrl* mMediaResetCtrl;
LLSpinCtrl* mMediaHeightCtrl;
LLSpinCtrl* mMediaWidthCtrl;
LLTextBox* mMediaResetCtrlLabel;
@@ -74,13 +72,6 @@ private:
LLCheckBoxCtrl* mMediaLoopCheck;
LLCheckBoxCtrl* mMediaUrlCheck;
LLHandle<LLFloater> mURLEntryFloater;
- LLCheckBoxCtrl* mMediaNavigateAllowCheck;
- LLCheckBoxCtrl* mMediaURLFilterCheck;
- LLLineEditor* mMediaURLFilterDomainEdit;
- LLButton* mMediaURLFilterAddButton;
- LLButton* mMediaURLFilterRemoveButton;
- LLScrollListCtrl* mURLFilterList;
- LLRadioGroup* mRadioNavigateControl;
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 150fd399c6..a7f66f3293 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -57,6 +57,7 @@
#include "lluiconstants.h"
#include "llurlsimstring.h"
#include "llviewerbuild.h"
+#include "llviewerhelp.h"
#include "llviewertexturelist.h"
#include "llviewermenu.h" // for handle_preferences()
#include "llviewernetwork.h"
@@ -69,7 +70,7 @@
#include "llmediactrl.h"
#include "llrootview.h"
-#include "llfloatermediabrowser.h"
+
#include "llfloatertos.h"
#include "lltrans.h"
#include "llglheaders.h"
@@ -229,7 +230,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
server_choice_combo->setCommitCallback(onSelectServer, NULL);
- server_choice_combo->setFocusLostCallback(onServerComboLostFocus);
+ server_choice_combo->setFocusLostCallback(boost::bind(onServerComboLostFocus, _1));
childSetAction("connect_btn", onClickConnect, this);
@@ -412,8 +413,8 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask)
if ( KEY_F1 == key )
{
- llinfos << "Spawning HTML help window" << llendl;
- gViewerHtmlHelp.show();
+ LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+ vhelp->showTopic(vhelp->getTopicFromFocus());
return TRUE;
}
@@ -973,7 +974,7 @@ void LLPanelLogin::onSelectServer(LLUICtrl*, void*)
loadLoginPage();
}
-void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*)
+void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe)
{
if (!sInstance) return;
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index ffcf6a9b70..5692b8d345 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -94,7 +94,7 @@ private:
static void onClickForgotPassword(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
static void onSelectServer(LLUICtrl*, void*);
- static void onServerComboLostFocus(LLFocusableElement*, void*);
+ static void onServerComboLostFocus(LLFocusableElement*);
private:
LLPointer<LLUIImage> mLogoImage;
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
new file mode 100644
index 0000000000..be40d6fb5f
--- /dev/null
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -0,0 +1,409 @@
+/**
+ * @file llpanelmediasettingsgeneral.cpp
+ * @brief LLPanelMediaSettingsGeneral class implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelmediasettingsgeneral.h"
+#include "llcombobox.h"
+#include "llcheckboxctrl.h"
+#include "llspinctrl.h"
+#include "lluictrlfactory.h"
+#include "llviewerwindow.h"
+#include "llsdutil.h"
+#include "llselectmgr.h"
+#include "llbutton.h"
+#include "lltexturectrl.h"
+#include "llurl.h"
+#include "llwindow.h"
+#include "llmediaentry.h"
+#include "llmediactrl.h"
+#include "llpanelcontents.h"
+#include "llpluginclassmedia.h"
+#include "llfloatermediasettings.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLPanelMediaSettingsGeneral::LLPanelMediaSettingsGeneral() :
+ mControls( NULL ),
+ mAutoLoop( NULL ),
+ mFirstClick( NULL ),
+ mAutoZoom( NULL ),
+ mAutoPlay( NULL ),
+ mAutoScale( NULL ),
+ mWidthPixels( NULL ),
+ mHeightPixels( NULL ),
+ mHomeURL( NULL ),
+ mCurrentURL( NULL ),
+ mAltImageEnable( NULL ),
+ mParent( NULL )
+{
+ // build dialog from XML
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_general.xml");
+ mCommitCallbackRegistrar.add("Media.ResetCurrentUrl", boost::bind(&LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl, this));
+// mCommitCallbackRegistrar.add("Media.CommitHomeURL", boost::bind(&LLPanelMediaSettingsGeneral::onCommitHomeURL, this));
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLPanelMediaSettingsGeneral::postBuild()
+{
+ // connect member vars with UI widgets
+ mAltImageEnable = getChild< LLCheckBoxCtrl >( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
+ mAutoLoop = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_LOOP_KEY );
+ mAutoPlay = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_PLAY_KEY );
+ mAutoScale = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_SCALE_KEY );
+ mAutoZoom = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_ZOOM_KEY );
+ mControls = getChild< LLComboBox >( LLMediaEntry::CONTROLS_KEY );
+ mCurrentURL = getChild< LLLineEditor >( LLMediaEntry::CURRENT_URL_KEY );
+ mFirstClick = getChild< LLCheckBoxCtrl >( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
+ mHeightPixels = getChild< LLSpinCtrl >( LLMediaEntry::HEIGHT_PIXELS_KEY );
+ mHomeURL = getChild< LLLineEditor >( LLMediaEntry::HOME_URL_KEY );
+ mWidthPixels = getChild< LLSpinCtrl >( LLMediaEntry::WIDTH_PIXELS_KEY );
+ mPreviewMedia = getChild<LLMediaCtrl>("preview_media");
+
+ // watch commit action for HOME URL
+ childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this);
+
+ // interrogates controls and updates widgets as required
+ updateMediaPreview();
+ updateCurrentURL();
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+LLPanelMediaSettingsGeneral::~LLPanelMediaSettingsGeneral()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsGeneral::draw()
+{
+ // housekeeping
+ LLPanel::draw();
+
+ // enable/disable pixel values image entry based on auto scale checkbox
+ if ( mAutoScale->getValue().asBoolean() == false )
+ {
+ childSetEnabled( LLMediaEntry::WIDTH_PIXELS_KEY, true );
+ childSetEnabled( LLMediaEntry::HEIGHT_PIXELS_KEY, true );
+ }
+ else
+ {
+ childSetEnabled( LLMediaEntry::WIDTH_PIXELS_KEY, false );
+ childSetEnabled( LLMediaEntry::HEIGHT_PIXELS_KEY, false );
+ };
+
+ // enable/disable UI based on type of media
+ bool reset_button_is_active = true;
+ if( mPreviewMedia )
+ {
+ LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin();
+ if( media_plugin )
+ {
+ // some controls are only appropriate for time or browser type plugins
+ // so we selectively enable/disable them - need to do it in draw
+ // because the information from plugins arrives assynchronously
+ bool show_time_controls = media_plugin->pluginSupportsMediaTime();
+ if ( show_time_controls )
+ {
+ childSetEnabled( LLMediaEntry::CURRENT_URL_KEY, false );
+ reset_button_is_active = false;
+ childSetEnabled( "current_url_label", false );
+ childSetEnabled( LLMediaEntry::AUTO_LOOP_KEY, true );
+ }
+ else
+ {
+ childSetEnabled( LLMediaEntry::CURRENT_URL_KEY, true );
+ reset_button_is_active = true;
+ childSetEnabled( "current_url_label", true );
+ childSetEnabled( LLMediaEntry::AUTO_LOOP_KEY, false );
+ };
+ };
+ };
+
+ // current URL can change over time.
+ updateCurrentURL();
+
+ // enable/disable RESRET button depending on permissions
+ // since this is the same as a navigate action
+ U32 owner_mask_on;
+ U32 owner_mask_off;
+ U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER,
+ &owner_mask_on, &owner_mask_off );
+ U32 group_mask_on;
+ U32 group_mask_off;
+ U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP,
+ &group_mask_on, &group_mask_off );
+ U32 everyone_mask_on;
+ U32 everyone_mask_off;
+ S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE,
+ &everyone_mask_on, &everyone_mask_off );
+
+ bool user_can_press_reset = false;
+
+ // if perms we got back are valid
+ if ( valid_owner_perms &&
+ valid_group_perms &&
+ valid_everyone_perms )
+ {
+ // if user is allowed to press the RESET button
+ if ( ( owner_mask_on & PERM_MODIFY ) ||
+ ( group_mask_on & PERM_MODIFY ) ||
+ ( group_mask_on & PERM_MODIFY ) )
+ {
+ user_can_press_reset = true;
+ }
+ else
+ // user is NOT allowed to press the RESET button
+ {
+ user_can_press_reset = false;
+ };
+ };
+
+ // several places modify this widget so we must collect states in one place
+ if ( reset_button_is_active )
+ {
+ // user has perms to press reset button and it is active
+ if ( user_can_press_reset )
+ {
+ childSetEnabled( "current_url_reset_btn", true );
+ }
+ // user does not has perms to press reset button and it is active
+ else
+ {
+ childSetEnabled( "current_url_reset_btn", false );
+ };
+ }
+ else
+ // reset button is inactive so we just slam it to off - other states don't matter
+ {
+ childSetEnabled( "current_url_reset_btn", false );
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsGeneral::clearValues( void* userdata )
+{
+ LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
+ self->mAltImageEnable ->clear();
+ self->mAutoLoop->clear();
+ self->mAutoPlay->clear();
+ self->mAutoScale->clear();
+ self->mAutoZoom ->clear();
+ self->mControls->clear();
+ self->mCurrentURL->clear();
+ self->mFirstClick->clear();
+ self->mHeightPixels->clear();
+ self->mHomeURL->clear();
+ self->mWidthPixels->clear();
+ self->mPreviewMedia->unloadMediaSource();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_settings )
+{
+ LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
+
+ //llinfos << "---------------" << llendl;
+ //llinfos << ll_pretty_print_sd(media_settings) << llendl;
+ //llinfos << "---------------" << llendl;
+
+ std::string base_key( "" );
+ std::string tentative_key( "" );
+
+ struct
+ {
+ std::string key_name;
+ LLUICtrl* ctrl_ptr;
+ std::string ctrl_type;
+
+ } data_set [] =
+ {
+ { LLMediaEntry::AUTO_LOOP_KEY, self->mAutoLoop, "LLCheckBoxCtrl" },
+ { LLMediaEntry::AUTO_PLAY_KEY, self->mAutoPlay, "LLCheckBoxCtrl" },
+ { LLMediaEntry::AUTO_SCALE_KEY, self->mAutoScale, "LLCheckBoxCtrl" },
+ { LLMediaEntry::AUTO_ZOOM_KEY, self->mAutoZoom, "LLCheckBoxCtrl" },
+ { LLMediaEntry::CONTROLS_KEY, self->mControls, "LLComboBox" },
+ { LLMediaEntry::CURRENT_URL_KEY, self->mCurrentURL, "LLLineEditor" },
+ { LLMediaEntry::HEIGHT_PIXELS_KEY, self->mHeightPixels, "LLSpinCtrl" },
+ { LLMediaEntry::HOME_URL_KEY, self->mHomeURL, "LLLineEditor" },
+ { LLMediaEntry::FIRST_CLICK_INTERACT_KEY, self->mFirstClick, "LLCheckBoxCtrl" },
+ { LLMediaEntry::WIDTH_PIXELS_KEY, self->mWidthPixels, "LLSpinCtrl" },
+ { LLMediaEntry::ALT_IMAGE_ENABLE_KEY, self->mAltImageEnable, "LLCheckBoxCtrl" },
+ { "", NULL , "" }
+ };
+
+ for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
+ {
+ base_key = std::string( data_set[ i ].key_name );
+ tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
+ // TODO: CP - I bet there is a better way to do this using Boost
+ if ( media_settings[ base_key ].isDefined() )
+ {
+ if ( data_set[ i ].ctrl_type == "LLLineEditor" )
+ {
+ static_cast< LLLineEditor* >( data_set[ i ].ctrl_ptr )->
+ setText( media_settings[ base_key ].asString() );
+ }
+ else
+ if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
+ static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
+ setValue( media_settings[ base_key ].asBoolean() );
+ else
+ if ( data_set[ i ].ctrl_type == "LLComboBox" )
+ static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )->
+ setCurrentByIndex( media_settings[ base_key ].asInteger() );
+ else
+ if ( data_set[ i ].ctrl_type == "LLSpinCtrl" )
+ static_cast< LLSpinCtrl* >( data_set[ i ].ctrl_ptr )->
+ setValue( media_settings[ base_key ].asInteger() );
+
+ data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
+ };
+ };
+
+ // interrogates controls and updates widgets as required
+ self->updateMediaPreview();
+ self->updateCurrentURL();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper to set media control to media URL as required
+void LLPanelMediaSettingsGeneral::updateMediaPreview()
+{
+ if ( mHomeURL->getValue().asString().length() > 0 )
+ {
+ mPreviewMedia->navigateTo( mHomeURL->getValue().asString() );
+ }
+ else
+ // new home URL will be empty if media is deleted but
+ // we still need to clean out the preview.
+ {
+ mPreviewMedia->unloadMediaSource();
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper to set current URL
+void LLPanelMediaSettingsGeneral::updateCurrentURL()
+{
+ if( mPreviewMedia )
+ {
+ LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin();
+ if( media_plugin )
+ {
+ // get current URL from plugin and display
+ std::string current_location = media_plugin->getLocation();
+ if ( current_location.length() )
+ {
+ childSetText( "current_url", current_location );
+ }
+ else
+ // current location may be empty so we need to clear it
+ {
+ const std::string empty_string( "" );
+ childSetText( "current_url", empty_string );
+ };
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void LLPanelMediaSettingsGeneral::onClose()
+{
+ if(mPreviewMedia)
+ {
+ mPreviewMedia->unloadMediaSource();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsGeneral::onCommitHomeURL( LLUICtrl* ctrl, void *userdata )
+{
+ LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata;
+ self->updateMediaPreview();
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+void LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl()
+{
+ // TODO: reset home URL but need to consider permissions too
+ //LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsGeneral::apply( void* userdata )
+{
+ LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
+
+ // build LLSD Fragment
+ LLSD media_data_general;
+ self->getValues(media_data_general);
+
+ // this merges contents of LLSD passed in with what's there so this is ok
+ LLSelectMgr::getInstance()->selectionSetMediaData( media_data_general );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in )
+{
+ fill_me_in[LLMediaEntry::ALT_IMAGE_ENABLE_KEY] = mAltImageEnable->getValue();
+ fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = mAutoLoop->getValue();
+ fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = mAutoPlay->getValue();
+ fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = mAutoScale->getValue();
+ fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = mAutoZoom->getValue();
+ fill_me_in[LLMediaEntry::CONTROLS_KEY] = mControls->getCurrentIndex();
+ // XXX Don't send current URL!
+ //fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue();
+ fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = mHeightPixels->getValue();
+ fill_me_in[LLMediaEntry::HOME_URL_KEY] = mHomeURL->getValue();
+ fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = mFirstClick->getValue();
+ fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = mWidthPixels->getValue();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelMediaSettingsGeneral::setParent( LLFloaterMediaSettings* parent )
+{
+ mParent = parent;
+};
diff --git a/indra/newview/llpanelmediasettingsgeneral.h b/indra/newview/llpanelmediasettingsgeneral.h
new file mode 100644
index 0000000000..24678a3a07
--- /dev/null
+++ b/indra/newview/llpanelmediasettingsgeneral.h
@@ -0,0 +1,89 @@
+/**
+ * @file llpanelmediasettingsgeneral.h
+ * @brief LLPanelMediaSettingsGeneral class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H
+#define LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H
+
+#include "llpanel.h"
+
+class LLButton;
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLLineEditor;
+class LLSpinCtrl;
+class LLTextureCtrl;
+class LLMediaCtrl;
+class LLFloaterMediaSettings;
+
+class LLPanelMediaSettingsGeneral : public LLPanel
+{
+public:
+ BOOL postBuild();
+ virtual void draw();
+ static void apply(void*);
+ void getValues(LLSD &fill_me_in);
+
+ LLPanelMediaSettingsGeneral();
+ ~LLPanelMediaSettingsGeneral();
+
+ void setParent( LLFloaterMediaSettings* parent );
+ static void initValues( void* userdata, const LLSD& media_settings );
+ static void clearValues( void* userdata );
+
+ void updateMediaPreview();
+ void updateCurrentURL();
+
+ void onClose();
+
+protected:
+ LLFloaterMediaSettings* mParent;
+
+private:
+ void onBtnResetCurrentUrl();
+ static void onCommitHomeURL(LLUICtrl* ctrl, void *userdata );
+
+ LLComboBox* mControls;
+ LLCheckBoxCtrl* mAutoLoop;
+ LLCheckBoxCtrl* mFirstClick;
+ LLTextureCtrl* mMediaPreview;
+ LLCheckBoxCtrl* mAutoZoom;
+ LLCheckBoxCtrl* mAutoPlay;
+ LLCheckBoxCtrl* mAutoScale;
+ LLSpinCtrl* mWidthPixels;
+ LLSpinCtrl* mHeightPixels;
+ LLLineEditor* mHomeURL;
+ LLLineEditor* mCurrentURL;
+ LLCheckBoxCtrl* mAltImageEnable;
+ LLMediaCtrl* mPreviewMedia;
+};
+
+#endif // LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H
diff --git a/indra/newview/llpanelmediasettingspermissions.cpp b/indra/newview/llpanelmediasettingspermissions.cpp
new file mode 100644
index 0000000000..d6a2677f4b
--- /dev/null
+++ b/indra/newview/llpanelmediasettingspermissions.cpp
@@ -0,0 +1,223 @@
+/**
+ * @file llpanelmediasettingspermissions.cpp
+ * @brief LLPanelMediaSettingsPermissions class implementation
+ *
+ * note that "permissions" tab is really "Controls" tab - refs to 'perms' and
+ * 'permissions' not changed to 'controls' since we don't want to change
+ * shared files in server code and keeping everything the same seemed best.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelmediasettingspermissions.h"
+#include "llpanelcontents.h"
+#include "llcombobox.h"
+#include "llcheckboxctrl.h"
+#include "llspinctrl.h"
+#include "llurlhistory.h"
+#include "lluictrlfactory.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "llsdutil.h"
+#include "llselectmgr.h"
+#include "llmediaentry.h"
+#include "llnamebox.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLPanelMediaSettingsPermissions::LLPanelMediaSettingsPermissions() :
+ mPermsOwnerInteract( 0 ),
+ mPermsOwnerControl( 0 ),
+ mPermsGroupName( 0 ),
+ mPermsGroupInteract( 0 ),
+ mPermsGroupControl( 0 ),
+ mPermsWorldInteract( 0 ),
+ mPermsWorldControl( 0 )
+{
+ // build dialog from XML
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_permissions.xml");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLPanelMediaSettingsPermissions::postBuild()
+{
+ // connect member vars with UI widgets
+ mPermsOwnerInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
+ mPermsOwnerControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
+ mPermsGroupInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
+ mPermsGroupControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
+ mPermsWorldInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
+ mPermsWorldControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
+
+ mPermsGroupName = getChild< LLNameBox >( "perms_group_name" );
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+LLPanelMediaSettingsPermissions::~LLPanelMediaSettingsPermissions()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+void LLPanelMediaSettingsPermissions::draw()
+{
+ // housekeeping
+ LLPanel::draw();
+
+ childSetText("perms_group_name",LLStringUtil::null);
+ LLUUID group_id;
+ BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id);
+ if (groups_identical)
+ {
+ if(mPermsGroupName)
+ {
+ mPermsGroupName->setNameID(group_id, true);
+ mPermsGroupName->setEnabled(true);
+ };
+ }
+ else
+ {
+ if(mPermsGroupName)
+ {
+ mPermsGroupName->setNameID(LLUUID::null, TRUE);
+ mPermsGroupName->refresh(LLUUID::null, LLStringUtil::null, LLStringUtil::null, true);
+ mPermsGroupName->setEnabled(false);
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsPermissions::clearValues( void* userdata )
+{
+ LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata;
+ self->mPermsOwnerInteract->clear();
+ self->mPermsOwnerControl->clear();
+ self->mPermsGroupInteract ->clear();
+ self->mPermsGroupControl->clear();
+ self->mPermsWorldInteract ->clear();
+ self->mPermsWorldControl ->clear();
+// mPermsGroupName ->setValue(0);
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& media_settings )
+{
+ LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata;
+
+ std::string base_key( "" );
+ std::string tentative_key( "" );
+
+ struct
+ {
+ std::string key_name;
+ LLUICtrl* ctrl_ptr;
+ std::string ctrl_type;
+
+ } data_set [] =
+ {
+ { LLPanelContents::PERMS_OWNER_INTERACT_KEY, self->mPermsOwnerInteract, "LLCheckBoxCtrl" },
+ { LLPanelContents::PERMS_OWNER_CONTROL_KEY, self->mPermsOwnerControl, "LLCheckBoxCtrl" },
+ { LLPanelContents::PERMS_GROUP_INTERACT_KEY, self->mPermsGroupInteract, "LLCheckBoxCtrl" },
+ { LLPanelContents::PERMS_GROUP_CONTROL_KEY, self->mPermsGroupControl, "LLCheckBoxCtrl" },
+ { LLPanelContents::PERMS_ANYONE_INTERACT_KEY, self->mPermsWorldInteract, "LLCheckBoxCtrl" },
+ { LLPanelContents::PERMS_ANYONE_CONTROL_KEY, self->mPermsWorldControl, "LLCheckBoxCtrl" },
+ { "", NULL , "" }
+ };
+
+ for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
+ {
+ base_key = std::string( data_set[ i ].key_name );
+ tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
+
+ // TODO: CP - I bet there is a better way to do this using Boost
+ if ( media_settings[ base_key ].isDefined() )
+ {
+ if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
+ {
+ // the sense of the checkboxes changed and it made sense
+ // to just reverse their sense back again here and avoid
+ // changing server code.
+ static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
+ setValue( ! media_settings[ base_key ].asBoolean() );
+ }
+ else
+ if ( data_set[ i ].ctrl_type == "LLComboBox" )
+ static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )->
+ setCurrentByIndex( media_settings[ base_key ].asInteger() );
+
+ data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsPermissions::apply( void* userdata )
+{
+ LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata;
+
+ // build LLSD Fragment
+ LLSD media_data_permissions;
+ self->getValues(media_data_permissions);
+
+ // this merges contents of LLSD passed in with what's there so this is ok
+ LLSelectMgr::getInstance()->selectionSetMediaData( media_data_permissions );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelMediaSettingsPermissions::getValues( LLSD &fill_me_in )
+{
+ // *NOTE: For some reason, gcc does not like these symbol references in the
+ // expressions below (inside the static_casts). I have NO idea why :(.
+ // For some reason, assigning them to const temp vars here fixes the link
+ // error. Bizarre.
+ const U8 none = LLMediaEntry::PERM_NONE;
+ const U8 owner = LLMediaEntry::PERM_OWNER;
+ const U8 group = LLMediaEntry::PERM_GROUP;
+ const U8 anyone = LLMediaEntry::PERM_ANYONE;
+ const LLSD::Integer control = static_cast<LLSD::Integer>(
+ (mPermsOwnerControl->getValue() ? none : owner ) |
+ (mPermsGroupControl->getValue() ? none : group ) |
+ (mPermsWorldControl->getValue() ? none : anyone ));
+ const LLSD::Integer interact = static_cast<LLSD::Integer>(
+ (mPermsOwnerInteract->getValue() ? none : owner ) |
+ (mPermsGroupInteract->getValue() ? none : group ) |
+ (mPermsWorldInteract->getValue() ? none : anyone ));
+ fill_me_in[LLMediaEntry::PERMS_CONTROL_KEY] = control;
+ fill_me_in[LLMediaEntry::PERMS_INTERACT_KEY] = interact;
+}
diff --git a/indra/newview/llpanelmediasettingspermissions.h b/indra/newview/llpanelmediasettingspermissions.h
new file mode 100644
index 0000000000..ce293e07b9
--- /dev/null
+++ b/indra/newview/llpanelmediasettingspermissions.h
@@ -0,0 +1,71 @@
+/**
+ * @file llpanelmediasettingspermissions.h
+ * @brief LLPanelMediaSettingsPermissions class definition
+ *
+ * note that "permissions" tab is really "Controls" tab - refs to 'perms' and
+ * 'permissions' not changed to 'controls' since we don't want to change
+ * shared files in server code and keeping everything the same seemed best.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H
+#define LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H
+
+#include "llpanel.h"
+#include "lluuid.h"
+
+class LLComboBox;
+class LLCheckBoxCtrl;
+class LLNameBox;
+
+class LLPanelMediaSettingsPermissions : public LLPanel
+{
+ public:
+ BOOL postBuild();
+ virtual void draw();
+ static void apply(void*);
+ void getValues(LLSD &fill_me_in);
+
+ LLPanelMediaSettingsPermissions();
+ ~LLPanelMediaSettingsPermissions();
+
+ static void initValues( void* userdata, const LLSD& media_settings );
+ static void clearValues( void* userdata );
+
+ private:
+ LLCheckBoxCtrl* mPermsOwnerInteract;
+ LLCheckBoxCtrl* mPermsOwnerControl;
+ LLNameBox* mPermsGroupName;
+ LLCheckBoxCtrl* mPermsGroupInteract;
+ LLCheckBoxCtrl* mPermsGroupControl;
+ LLCheckBoxCtrl* mPermsWorldInteract;
+ LLCheckBoxCtrl* mPermsWorldControl;
+};
+
+#endif // LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H
diff --git a/indra/newview/llpanelmediasettingssecurity.cpp b/indra/newview/llpanelmediasettingssecurity.cpp
new file mode 100644
index 0000000000..a4eee82aa9
--- /dev/null
+++ b/indra/newview/llpanelmediasettingssecurity.cpp
@@ -0,0 +1,233 @@
+/**
+ * @file llpanelmediasettingssecurity.cpp
+ * @brief LLPanelMediaSettingsSecurity class implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterreg.h"
+#include "llpanelmediasettingssecurity.h"
+#include "llpanelcontents.h"
+#include "llcheckboxctrl.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "lluictrlfactory.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "llsdutil.h"
+#include "llselectmgr.h"
+#include "llmediaentry.h"
+#include "llfloaterwhitelistentry.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLPanelMediaSettingsSecurity::LLPanelMediaSettingsSecurity()
+{
+ // build dialog from XML
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_security.xml");
+ mCommitCallbackRegistrar.add("Media.whitelistAdd", boost::bind(&LLPanelMediaSettingsSecurity::onBtnAdd, this));
+ mCommitCallbackRegistrar.add("Media.whitelistDelete", boost::bind(&LLPanelMediaSettingsSecurity::onBtnDel, this));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLPanelMediaSettingsSecurity::postBuild()
+{
+ mEnableWhiteList = getChild< LLCheckBoxCtrl >( LLMediaEntry::WHITELIST_ENABLE_KEY );
+ mWhiteListList = getChild< LLScrollListCtrl >( LLMediaEntry::WHITELIST_KEY );
+
+ childSetAction("whitelist_add", onBtnAdd, this);
+ childSetAction("whitelist_del", onBtnDel, this);
+
+ setDefaultBtn("whitelist_add");
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+LLPanelMediaSettingsSecurity::~LLPanelMediaSettingsSecurity()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelMediaSettingsSecurity::draw()
+{
+ // housekeeping
+ LLPanel::draw();
+
+ // if list is empty, disable DEL button and checkbox to enable use of list
+ if ( mWhiteListList->isEmpty() )
+ {
+ childSetEnabled( "whitelist_del", false );
+ childSetEnabled( LLMediaEntry::WHITELIST_KEY, false );
+ childSetEnabled( LLMediaEntry::WHITELIST_ENABLE_KEY, false );
+ }
+ else
+ {
+ childSetEnabled( "whitelist_del", true );
+ childSetEnabled( LLMediaEntry::WHITELIST_KEY, true );
+ childSetEnabled( LLMediaEntry::WHITELIST_ENABLE_KEY, true );
+ };
+
+ // if nothing is selected, disable DEL button
+ if ( mWhiteListList->getSelectedValue().asString().empty() )
+ {
+ childSetEnabled( "whitelist_del", false );
+ }
+ else
+ {
+ childSetEnabled( "whitelist_del", true );
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media_settings )
+{
+ LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
+
+ std::string base_key( "" );
+ std::string tentative_key( "" );
+
+ struct
+ {
+ std::string key_name;
+ LLUICtrl* ctrl_ptr;
+ std::string ctrl_type;
+
+ } data_set [] =
+ {
+ { LLMediaEntry::WHITELIST_ENABLE_KEY, self->mEnableWhiteList, "LLCheckBoxCtrl" },
+ { LLMediaEntry::WHITELIST_KEY, self->mWhiteListList, "LLScrollListCtrl" },
+ { "", NULL , "" }
+ };
+
+ for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
+ {
+ base_key = std::string( data_set[ i ].key_name );
+ tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
+
+ // TODO: CP - I bet there is a better way to do this using Boost
+ if ( media_settings[ base_key ].isDefined() )
+ {
+ if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
+ {
+ static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
+ setValue( media_settings[ base_key ].asBoolean() );
+ }
+ else
+ if ( data_set[ i ].ctrl_type == "LLScrollListCtrl" )
+ {
+ // get control
+ LLScrollListCtrl* list = static_cast< LLScrollListCtrl* >( data_set[ i ].ctrl_ptr );
+ list->deleteAllItems();
+
+ // points to list of white list URLs
+ LLSD url_list = media_settings[ base_key ];
+
+ // iterate over them and add to scroll list
+ LLSD::array_iterator iter = url_list.beginArray();
+ while( iter != url_list.endArray() )
+ {
+ // TODO: is iter guaranteed to be valid here?
+ std::string url = *iter;
+ list->addSimpleElement( url );
+ ++iter;
+ };
+ };
+
+ data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsSecurity::clearValues( void* userdata )
+{
+ LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
+ self->mEnableWhiteList->clear();
+ self->mWhiteListList->deleteAllItems();
+}
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsSecurity::apply( void* userdata )
+{
+ LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
+
+ // build LLSD Fragment
+ LLSD media_data_security;
+ self->getValues(media_data_security);
+ // this merges contents of LLSD passed in with what's there so this is ok
+ LLSelectMgr::getInstance()->selectionSetMediaData( media_data_security );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelMediaSettingsSecurity::getValues( LLSD &fill_me_in )
+{
+ fill_me_in[LLMediaEntry::WHITELIST_ENABLE_KEY] = mEnableWhiteList->getValue();
+
+ // iterate over white list and extract items
+ std::vector< LLScrollListItem* > white_list_items = mWhiteListList->getAllData();
+ std::vector< LLScrollListItem* >::iterator iter = white_list_items.begin();
+ fill_me_in[LLMediaEntry::WHITELIST_KEY].clear();
+ while( iter != white_list_items.end() )
+ {
+ std::string white_list_url = (*iter)->getValue().asString();
+ fill_me_in[ LLMediaEntry::WHITELIST_KEY ].append( white_list_url );
+ ++iter;
+ };
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsSecurity::addWhiteListItem(const std::string& url)
+{
+ mWhiteListList->addSimpleElement( url );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsSecurity::onBtnAdd( void* userdata )
+{
+ LLFloaterReg::showInstance("whitelist_entry");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsSecurity::onBtnDel( void* userdata )
+{
+ LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
+
+ self->mWhiteListList->deleteSelectedItems();
+}
diff --git a/indra/newview/llpanelmediasettingssecurity.h b/indra/newview/llpanelmediasettingssecurity.h
new file mode 100644
index 0000000000..d77509897d
--- /dev/null
+++ b/indra/newview/llpanelmediasettingssecurity.h
@@ -0,0 +1,64 @@
+/**
+ * @file llpanelmediasettingssecurity.h
+ * @brief LLPanelMediaSettingsSecurity class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H
+#define LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H
+
+#include "llpanel.h"
+
+class LLCheckBoxCtrl;
+class LLScrollListCtrl;
+
+class LLPanelMediaSettingsSecurity : public LLPanel
+{
+ public:
+ BOOL postBuild();
+ virtual void draw();
+ static void apply(void*);
+ void getValues(LLSD &fill_me_in);
+
+ LLPanelMediaSettingsSecurity();
+ ~LLPanelMediaSettingsSecurity();
+
+ static void initValues( void* userdata, const LLSD& media_settings );
+ static void clearValues( void* userdata );
+ void addWhiteListItem(const std::string& url);
+
+ private:
+ LLCheckBoxCtrl* mEnableWhiteList;
+ LLScrollListCtrl* mWhiteListList;
+
+ static void onBtnAdd(void*);
+ static void onBtnDel(void*);
+};
+
+#endif // LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 6a41b6feb9..b2a0a01005 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -60,11 +60,8 @@
#include "llvoiceclient.h"
#include "llworld.h"
-using namespace LLOldEvents;
-
#define FRIEND_LIST_UPDATE_TIMEOUT 0.5
#define NEARBY_LIST_UPDATE_INTERVAL 1
-#define RECENT_LIST_UPDATE_DELAY 1
static const std::string NEARBY_TAB_NAME = "nearby_panel";
static const std::string FRIENDS_TAB_NAME = "friends_panel";
@@ -102,7 +99,7 @@ static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people");
class LLPanelPeople::Updater
{
public:
- typedef boost::function<bool(U32)> callback_t;
+ typedef boost::function<void()> callback_t;
Updater(callback_t cb)
: mCallback(cb)
{
@@ -113,16 +110,6 @@ public:
}
/**
- * Force the list updates.
- *
- * This may start repeated updates until all names are complete.
- */
- virtual void forceUpdate()
- {
- updateList();
- }
-
- /**
* Activate/deactivate updater.
*
* This may start/stop regular updates.
@@ -130,9 +117,9 @@ public:
virtual void setActive(bool) {}
protected:
- bool updateList(U32 mask = 0)
+ void updateList()
{
- return mCallback(mask);
+ mCallback();
}
callback_t mCallback;
@@ -147,6 +134,11 @@ public:
{
mEventTimer.stop();
}
+
+ virtual BOOL tick() // from LLEventTimer
+ {
+ return FALSE;
+ }
};
/**
@@ -178,13 +170,6 @@ public:
LLAvatarTracker::instance().removeObserver(this);
}
- /*virtual*/ void forceUpdate()
- {
- // Perform updates until all names are loaded.
- if (!updateList(LLFriendObserver::ADD))
- changed(LLFriendObserver::ADD);
- }
-
/*virtual*/ void changed(U32 mask)
{
// events can arrive quickly in bulk - we need not process EVERY one of them -
@@ -198,12 +183,12 @@ public:
/*virtual*/ BOOL tick()
{
- if (updateList(mMask))
- {
- // Got all names, stop updates.
- mEventTimer.stop();
- mMask = 0;
- }
+ if (mMask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
+ updateList();
+
+ // Stop updates.
+ mEventTimer.stop();
+ mMask = 0;
return FALSE;
}
@@ -329,68 +314,9 @@ class LLRecentListUpdater : public LLAvatarListUpdater, public boost::signals2::
public:
LLRecentListUpdater(callback_t cb)
- : LLAvatarListUpdater(cb, RECENT_LIST_UPDATE_DELAY)
- {
- LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::onRecentPeopleChanged, this));
- }
-
-private:
- /*virtual*/ void forceUpdate()
- {
- onRecentPeopleChanged();
- }
-
- /*virtual*/ BOOL tick()
- {
- // Update the list until we get all the names.
- if (updateList())
- {
- // Got all names, stop updates.
- mEventTimer.stop();
- }
-
- return FALSE;
- }
-
- void onRecentPeopleChanged()
- {
- if (!updateList())
- {
- // Some names are incomplete, schedule another update.
- mEventTimer.start();
- }
- }
-};
-
-/**
- * Updates the group list on events from LLAgent.
- */
-class LLGroupListUpdater : public LLPanelPeople::Updater, public LLSimpleListener
-{
- LOG_CLASS(LLGroupListUpdater);
-
-public:
- LLGroupListUpdater(callback_t cb)
- : LLPanelPeople::Updater(cb)
- {
- gAgent.addListener(this, "new group");
- }
-
- ~LLGroupListUpdater()
+ : LLAvatarListUpdater(cb, 0)
{
- gAgent.removeListener(this);
- }
-
- /*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- // Why is "new group" sufficient?
- if (event->desc() == "new group")
- {
- updateList();
- return true;
- }
-
- return false;
+ LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::updateList, this));
}
};
@@ -404,12 +330,12 @@ LLPanelPeople::LLPanelPeople()
mOnlineFriendList(NULL),
mAllFriendList(NULL),
mNearbyList(NULL),
- mRecentList(NULL)
+ mRecentList(NULL),
+ mGroupList(NULL)
{
- mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::onFriendListUpdate,this, _1));
+ mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList, this));
mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this));
mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList, this));
- mGroupListUpdater = new LLGroupListUpdater (boost::bind(&LLPanelPeople::updateGroupList, this));
}
LLPanelPeople::~LLPanelPeople()
@@ -417,7 +343,6 @@ LLPanelPeople::~LLPanelPeople()
delete mNearbyListUpdater;
delete mFriendListUpdater;
delete mRecentListUpdater;
- delete mGroupListUpdater;
LLView::deleteViewByHandle(mGroupPlusMenuHandle);
LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);
@@ -512,7 +437,7 @@ BOOL LLPanelPeople::postBuild()
buttonSetAction("share_btn", boost::bind(&LLPanelPeople::onShareButtonClicked, this));
getChild<LLPanel>(NEARBY_TAB_NAME)->childSetAction("nearby_view_sort_btn",boost::bind(&LLPanelPeople::onNearbyViewSortButtonClicked, this));
- getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked, this));
+ getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked, this));
getChild<LLPanel>(FRIENDS_TAB_NAME)->childSetAction("friends_viewsort_btn",boost::bind(&LLPanelPeople::onFriendsViewSortButtonClicked, this));
getChild<LLPanel>(GROUP_TAB_NAME)->childSetAction("groups_viewsort_btn",boost::bind(&LLPanelPeople::onGroupsViewSortButtonClicked, this));
@@ -547,137 +472,71 @@ BOOL LLPanelPeople::postBuild()
if(recent_view_sort)
mRecentViewSortMenuHandle = recent_view_sort->getHandle();
-
-
- // Perform initial update.
- mFriendListUpdater->forceUpdate();
- mNearbyListUpdater->forceUpdate();
- mGroupListUpdater->forceUpdate();
- mRecentListUpdater->forceUpdate();
-
// call this method in case some list is empty and buttons can be in inconsistent state
updateButtons();
return TRUE;
}
-void LLPanelPeople::applyFilterToTab(const std::string& tab_name)
-{
- if (tab_name == FRIENDS_TAB_NAME) // this tab has two lists
- filterFriendList();
- else if (tab_name == NEARBY_TAB_NAME)
- filterNearbyList();
- else if (tab_name == RECENT_TAB_NAME)
- filterRecentList();
- else if (tab_name == GROUP_TAB_NAME)
- updateGroupList();
-}
-
-bool LLPanelPeople::updateFriendList(U32 changed_mask)
+void LLPanelPeople::updateFriendList()
{
- // Refresh names.
- if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
- {
- // get all buddies we know about
- const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
- LLAvatarTracker::buddy_map_t all_buddies;
- av_tracker.copyBuddyList(all_buddies);
-
- // *TODO: it's suboptimal to rebuild the whole lists on online status change.
+ if (!mOnlineFriendList || !mAllFriendList)
+ return;
- // save them to the online and all friends vectors
- mOnlineFriendVec.clear();
- mAllFriendVec.clear();
+ // get all buddies we know about
+ const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
+ LLAvatarTracker::buddy_map_t all_buddies;
+ av_tracker.copyBuddyList(all_buddies);
- LLFriendCardsManager::folderid_buddies_map_t listMap;
+ // save them to the online and all friends vectors
+ LLAvatarList::uuid_vector_t& online_friendsp = mOnlineFriendList->getIDs();
+ LLAvatarList::uuid_vector_t& all_friendsp = mAllFriendList->getIDs();
- // *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
- LLFriendCardsManager::instance().collectFriendsLists(listMap);
- if (listMap.size() > 0)
- {
- lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;
- mAllFriendVec = listMap.begin()->second;
- }
- else
- {
- lldebugs << "Friends Cards were not found" << llendl;
- }
+ all_friendsp.clear();
+ online_friendsp.clear();
- LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
- for (; buddy_it != all_buddies.end(); ++buddy_it)
- {
- LLUUID buddy_id = buddy_it->first;
- if (av_tracker.isBuddyOnline(buddy_id))
- mOnlineFriendVec.push_back(buddy_id);
- }
+ LLFriendCardsManager::folderid_buddies_map_t listMap;
- return filterFriendList();
+ // *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
+ LLFriendCardsManager::instance().collectFriendsLists(listMap);
+ if (listMap.size() > 0)
+ {
+ lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;
+ all_friendsp = listMap.begin()->second;
+ }
+ else
+ {
+ lldebugs << "Friends Cards were not found" << llendl;
}
- return true;
-}
-
-bool LLPanelPeople::updateNearbyList()
-{
- LLWorld::getInstance()->getAvatars(&mNearbyVec, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
- filterNearbyList();
-
- return true;
-}
-
-bool LLPanelPeople::updateRecentList()
-{
- LLRecentPeople::instance().get(mRecentVec);
- filterRecentList();
-
- return true;
-}
-
-bool LLPanelPeople::updateGroupList()
-{
- if (!mGroupList)
- return true; // there's no point in further updates
+ LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
+ for (; buddy_it != all_buddies.end(); ++buddy_it)
+ {
+ LLUUID buddy_id = buddy_it->first;
+ if (av_tracker.isBuddyOnline(buddy_id))
+ online_friendsp.push_back(buddy_id);
+ }
- bool have_names = mGroupList->update(mFilterSubString);
- updateButtons();
- return have_names;
+ mOnlineFriendList->setDirty();
+ mAllFriendList->setDirty();
}
-bool LLPanelPeople::filterFriendList()
+void LLPanelPeople::updateNearbyList()
{
- if (!mOnlineFriendList || !mAllFriendList)
- return true; // there's no point in further updates
-
- // We must always update Friends list to clear the latest removed friend.
- bool have_names =
- mOnlineFriendList->update(mOnlineFriendVec, mFilterSubString) &
- mAllFriendList->update(mAllFriendVec, mFilterSubString);
-
-
- updateButtons();
- return have_names;
-}
+ if (!mNearbyList)
+ return;
-bool LLPanelPeople::filterNearbyList()
-{
- bool have_names = mNearbyList->update(mNearbyVec, mFilterSubString);
- updateButtons();
- return have_names;
+ LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+ mNearbyList->setDirty();
}
-bool LLPanelPeople::filterRecentList()
+void LLPanelPeople::updateRecentList()
{
if (!mRecentList)
- return true;
-
- if (mRecentVec.size() > 0)
- {
- bool updated = mRecentList->update(mRecentVec, mFilterSubString);
- updateButtons();
- return updated;
- }
+ return;
- return true;
+ LLRecentPeople::instance().get(mRecentList->getIDs());
+ mRecentList->setDirty();
}
void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
@@ -846,16 +705,19 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
LLStringUtil::toUpper(mFilterSubString);
LLStringUtil::trimHead(mFilterSubString);
- // Apply new filter to current tab.
- applyFilterToTab(getActiveTabName());
+ // Apply new filter.
+ mNearbyList->setNameFilter(mFilterSubString);
+ mOnlineFriendList->setNameFilter(mFilterSubString);
+ mAllFriendList->setNameFilter(mFilterSubString);
+ mRecentList->setNameFilter(mFilterSubString);
+ mGroupList->setNameFilter(mFilterSubString);
}
void LLPanelPeople::onTabSelected(const LLSD& param)
{
std::string tab_name = getChild<LLPanel>(param.asString())->getName();
mNearbyListUpdater->setActive(tab_name == NEARBY_TAB_NAME);
- applyFilterToTab(tab_name);
- // No need to call updateButtons() because applyFilterToTab() does that.
+ updateButtons();
if (GROUP_TAB_NAME == tab_name)
mFilterEditor->setLabel(getString("groups_filter_label"));
@@ -960,17 +822,6 @@ void LLPanelPeople::onAvatarPicked(
LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
}
-bool LLPanelPeople::onFriendListUpdate(U32 changed_mask)
-{
- bool have_names = updateFriendList(changed_mask);
-
- // Update online status in the Recent tab.
- // *TODO: isn't it too much to update the whole list?
-// updateRecentList(); // mantipov: seems online status should be supported by LLAvatarListItem itself.
-
- return have_names;
-}
-
void LLPanelPeople::onGroupPlusButtonClicked()
{
LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 8cd3cc7feb..de27814388 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -58,15 +58,10 @@ public:
private:
// methods indirectly called by the updaters
- bool updateFriendList(U32 changed_mask);
- bool updateNearbyList();
- bool updateRecentList();
- bool updateGroupList();
-
- bool filterFriendList();
- bool filterNearbyList();
- bool filterRecentList();
- void applyFilterToTab(const std::string& tab_name);
+ void updateFriendList();
+ void updateNearbyList();
+ void updateRecentList();
+
void updateButtons();
const std::string& getActiveTabName() const;
LLUUID getCurrentItemID() const;
@@ -110,7 +105,6 @@ private:
void onRecentViewSortMenuItemClicked(const LLSD& userdata);
// misc callbacks
- bool onFriendListUpdate(U32 changed_mask);
static void onAvatarPicked(
const std::vector<std::string>& names,
const std::vector<LLUUID>& ids,
@@ -135,21 +129,8 @@ private:
Updater* mFriendListUpdater;
Updater* mNearbyListUpdater;
Updater* mRecentListUpdater;
- Updater* mGroupListUpdater;
std::string mFilterSubString;
-
- // The vectors below contain up-to date avatar lists
- // for the corresponding tabs.
- // When the user enters a filter, it gets applied
- // to all the vectors and the result is shown in the tabs.
- // We don't need to have such a vector for the groups tab
- // since re-fetching the groups list is always fast.
- typedef std::vector<LLUUID> uuid_vector_t;
- uuid_vector_t mNearbyVec;
- uuid_vector_t mOnlineFriendVec;
- uuid_vector_t mAllFriendVec;
- uuid_vector_t mRecentVec;
};
#endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 42185d28e5..5df3d4f1d6 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -39,8 +39,10 @@
#include "message.h"
#include "llagent.h"
#include "llbutton.h"
+#include "lllineeditor.h"
#include "llparcel.h"
#include "llviewerparcelmgr.h"
+#include "lltexteditor.h"
#include "lltexturectrl.h"
#include "lluiconstants.h"
#include "llworldmap.h"
@@ -73,7 +75,8 @@ LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */)
mPickId(LLUUID::null),
mCreatorId(LLUUID::null),
mDataReceived(FALSE),
- mIsPickNew(false)
+ mIsPickNew(false),
+ mLocationChanged(false)
{
if (edit_mode)
{
@@ -123,6 +126,16 @@ BOOL LLPanelPick::postBuild()
if (mEditMode)
{
+ enableSaveButton(FALSE);
+
+ mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1));
+
+ LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
+ line_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1), NULL);
+
+ LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
+ text_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1));
+
childSetAction("cancel_btn", boost::bind(&LLPanelPick::onClickCancel, this));
childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPick::onClickSet, this));
childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPick::onClickSave, this));
@@ -287,6 +300,26 @@ void LLPanelPick::setEditMode( BOOL edit_mode )
updateButtons();
}
+void LLPanelPick::onPickChanged(LLUICtrl* ctrl)
+{
+ if(mLocationChanged)
+ {
+ // Pick was enabled in onClickSet
+ return;
+ }
+
+ if( mSnapshotCtrl->isDirty()
+ || getChild<LLLineEditor>("pick_name")->isDirty()
+ || getChild<LLTextEditor>("pick_desc")->isDirty() )
+ {
+ enableSaveButton(TRUE);
+ }
+ else
+ {
+ enableSaveButton(FALSE);
+ }
+}
+
//////////////////////////////////////////////////////////////////////////
// PROTECTED AREA
//////////////////////////////////////////////////////////////////////////
@@ -466,6 +499,9 @@ void LLPanelPick::onClickSet()
mSimName = parcel->getName();
}
setPickLocation(createLocationText(std::string(""), SET_LOCATION_NOTICE, mSimName, mPosGlobal));
+
+ mLocationChanged = true;
+ enableSaveButton(TRUE);
}
// static
@@ -552,3 +588,12 @@ void LLPanelPick::processParcelInfo(const LLParcelData& parcel_data)
//*NOTE we don't removeObserver(...) ourselves cause LLRemoveParcelProcessor does it for us
}
+
+void LLPanelPick::enableSaveButton(bool enable)
+{
+ if(!mEditMode)
+ {
+ return;
+ }
+ childSetEnabled(XML_BTN_SAVE, enable);
+}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index 7ce58b59af..82cba72bc4 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -74,6 +74,8 @@ public:
// switches the panel to either View or Edit mode
void setEditMode(BOOL edit_mode);
+ void onPickChanged(LLUICtrl* ctrl);
+
// because this panel works in two modes (edit/view) we are
// free from managing two panel for editing and viewing picks and so
// are free from controlling switching between them in the parent panel (e.g. Me Profile)
@@ -128,6 +130,8 @@ protected:
void onClickSave();
void onClickCancel();
+ void enableSaveButton(bool enable);
+
protected:
BOOL mEditMode;
LLTextureCtrl* mSnapshotCtrl;
@@ -146,6 +150,7 @@ protected:
std::string mLocation;
commit_callback_t mBackCb;
+ bool mLocationChanged;
};
#endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 93317e613f..e74afba25a 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -126,8 +126,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
mPicksList->addItem(picture, pick_value);
picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1));
- picture->setRightMouseDownCallback(boost::bind(&LLPanelPicks::onRightMouseDownItem, this, _1, _2, _3, _4));
- picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
+ picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
}
@@ -260,8 +259,10 @@ void LLPanelPicks::onClickMap()
}
-void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
+void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
{
+ updateButtons();
+
if (mPopupMenu)
{
mPopupMenu->buildDrawLabels();
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 27a21305b3..7ebdc3089c 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -100,7 +100,7 @@ private:
void updateButtons();
virtual void onDoubleClickItem(LLUICtrl* item);
- virtual void onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
+ virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
LLPanelProfile* getProfilePanel();
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 4e070df7eb..80ecc95afb 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -337,7 +337,7 @@ void LLPanelPlaces::onFilterEdit(const std::string& search_string)
LLStringUtil::trimHead(mFilterSubString);
if (mActivePanel)
- mActivePanel->onSearchEdit(mFilterSubString);
+ mActivePanel->onSearchEdit(mFilterSubString);
}
}
@@ -386,7 +386,7 @@ void LLPanelPlaces::onTeleportButtonClicked()
else
{
if (mActivePanel)
- mActivePanel->onTeleport();
+ mActivePanel->onTeleport();
}
}
@@ -432,7 +432,7 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
else
{
if (mActivePanel)
- mActivePanel->onShowOnMap();
+ mActivePanel->onShowOnMap();
}
}
@@ -510,7 +510,7 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
addChild(mPickPanel);
mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- }
+ }
togglePickPanel(TRUE);
@@ -733,7 +733,7 @@ void LLPanelPlaces::updateVerbs()
else
{
if (mActivePanel)
- mActivePanel->updateVerbs();
+ mActivePanel->updateVerbs();
}
}
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index f6672d9c8b..9754094aaa 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -42,11 +42,15 @@
#include "llaccordionctrltab.h"
#include "llflatlistview.h"
#include "lltextbox.h"
+#include "llviewermenu.h"
+#include "llviewerinventory.h"
+#include "lllandmarkactions.h"
+#include "llclipboard.h"
class LLTeleportHistoryFlatItem : public LLPanel
{
public:
- LLTeleportHistoryFlatItem(S32 index, const std::string &region_name);
+ LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name);
virtual ~LLTeleportHistoryFlatItem() {};
virtual BOOL postBuild();
@@ -57,18 +61,23 @@ public:
void onMouseEnter(S32 x, S32 y, MASK mask);
void onMouseLeave(S32 x, S32 y, MASK mask);
+ virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+ static void showPlaceInfoPanel(S32 index);
private:
void onInfoBtnClick();
LLButton* mInfoBtn;
+ LLTeleportHistoryPanel::ContextMenu *mContextMenu;
S32 mIndex;
std::string mRegionName;
};
-LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, const std::string &region_name)
+LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name)
: LLPanel(),
mIndex(index),
+ mContextMenu(context_menu),
mRegionName(region_name)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history_item.xml");
@@ -109,15 +118,105 @@ void LLTeleportHistoryFlatItem::onMouseLeave(S32 x, S32 y, MASK mask)
LLPanel::onMouseLeave(x, y, mask);
}
-void LLTeleportHistoryFlatItem::onInfoBtnClick()
+// virtual
+BOOL LLTeleportHistoryFlatItem::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (mContextMenu)
+ mContextMenu->show(this, mIndex, x, y);
+
+ return LLPanel::handleRightMouseDown(x, y, mask);
+}
+
+void LLTeleportHistoryFlatItem::showPlaceInfoPanel(S32 index)
{
LLSD params;
- params["id"] = mIndex;
+ params["id"] = index;
params["type"] = "teleport_history";
LLSideTray::getInstance()->showPanel("panel_places", params);
}
+void LLTeleportHistoryFlatItem::onInfoBtnClick()
+{
+ LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);
+}
+
+LLTeleportHistoryPanel::ContextMenu::ContextMenu() :
+ mMenu(NULL)
+{
+}
+
+void LLTeleportHistoryPanel::ContextMenu::show(LLView* spawning_view, S32 index, S32 x, S32 y)
+{
+ if (mMenu)
+ {
+ //preventing parent (menu holder) from deleting already "dead" context menus on exit
+ LLView* parent = mMenu->getParent();
+ if (parent)
+ {
+ parent->removeChild(mMenu);
+ mMenu->setParent(NULL);
+ }
+ delete mMenu;
+ }
+
+ mIndex = index;
+ mMenu = createMenu();
+
+ LLViewerInventoryItem *landmark = LLLandmarkActions::findLandmarkForGlobalPos(
+ LLTeleportHistoryStorage::getInstance()->getItems()[index].mGlobalPos);
+
+ mMenu->setItemEnabled("Make Landmark", !landmark || landmark->getUUID().isNull());
+
+ mMenu->show(x, y);
+ LLMenuGL::showPopup(spawning_view, mMenu, x, y);
+}
+
+LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu()
+{
+ // set up the callbacks for all of the avatar menu items
+ // (N.B. callbacks don't take const refs as mID is local scope)
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ registrar.add("TeleportHistory.Teleport", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onTeleport, this));
+ registrar.add("TeleportHistory.MoreInformation",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onInfo, this));
+ registrar.add("TeleportHistory.Copy", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopy, this));
+ registrar.add("TeleportHistory.MakeLandmark", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onMakeLandmark, this));
+
+ // create the context menu from the XUI
+ return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+ "menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onTeleport()
+{
+ LLTeleportHistoryStorage::getInstance()->goToItem(mIndex);
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onInfo()
+{
+ LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);
+}
+
+//static
+void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& slurl)
+{
+ gClipboard.copyFromString(utf8str_to_wstring(slurl));
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onCopy()
+{
+ LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[mIndex].mGlobalPos;
+ LLLandmarkActions::getSLURLfromPosGlobal(globalPos,
+ boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1), false);
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onMakeLandmark()
+{
+ //FIXME: it creates landmark for current agent positon, not for the global position of item of teleport history
+ LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark"));
+}
+
// Not yet implemented; need to remove buildPanel() from constructor when we switch
//static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history");
@@ -126,6 +225,7 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()
mFilterSubString(LLStringUtil::null),
mTeleportHistory(NULL),
mHistoryAccordion(NULL),
+ mAccordionTabMenu(NULL),
mLastSelectedScrollList(NULL)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history.xml");
@@ -153,6 +253,8 @@ BOOL LLTeleportHistoryPanel::postBuild()
if (dynamic_cast<LLAccordionCtrlTab*>(*iter))
{
LLAccordionCtrlTab* tab = (LLAccordionCtrlTab*)*iter;
+ tab->setRightMouseDownCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionTabRightClick, this, _1, _2, _3, _4));
+
mItemContainers.put(tab);
LLFlatListView* fl = getFlatListViewFromTab(tab);
@@ -306,12 +408,12 @@ void LLTeleportHistoryPanel::showTeleportHistory()
if (curr_tab <= tabs_cnt - 4)
{
- curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
+ curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
}
else if (curr_tab == tabs_cnt - 3) // 6 day and older, low boundary is 1 month
{
curr_date = LLDate::now();
- curr_date.split(&curr_year, &curr_month, &curr_day);
+ curr_date.split(&curr_year, &curr_month, &curr_day);
curr_month--;
if (0 == curr_month)
{
@@ -354,7 +456,7 @@ void LLTeleportHistoryPanel::showTeleportHistory()
if (curr_flat_view)
{
- curr_flat_view->addItem(new LLTeleportHistoryFlatItem(index, (*iter).mTitle));
+ curr_flat_view->addItem(new LLTeleportHistoryFlatItem(index, &mContextMenu, (*iter).mTitle));
}
index--;
@@ -376,7 +478,7 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
S32 tabs_cnt = mItemContainers.size();
for (S32 n = 0; n < tabs_cnt; n++)
- {
+ {
LLAccordionCtrlTab* tab = mItemContainers.get(n);
if (!tab->getVisible())
@@ -390,7 +492,7 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
continue;
flv->resetSelection(true);
- }
+ }
updateVerbs();
}
@@ -411,6 +513,56 @@ void LLTeleportHistoryPanel::onDoubleClickItem(void* user_data)
LLSideTray::getInstance()->showPanel("panel_places", key);*/
}
+void LLTeleportHistoryPanel::onAccordionTabRightClick(LLView *view, S32 x, S32 y, MASK mask)
+{
+ LLAccordionCtrlTab *tab = (LLAccordionCtrlTab *) view;
+
+ // If click occurred below the header, don't show this menu
+ if (y < tab->getRect().getHeight() - tab->getHeaderHeight() - tab->getPaddingBottom())
+ return;
+
+ if (mAccordionTabMenu)
+ {
+ //preventing parent (menu holder) from deleting already "dead" context menus on exit
+ LLView* parent = mAccordionTabMenu->getParent();
+ if (parent)
+ {
+ parent->removeChild(mAccordionTabMenu);
+ mAccordionTabMenu->setParent(NULL);
+ }
+ delete mAccordionTabMenu;
+ }
+
+ // set up the callbacks for all of the avatar menu items
+ // (N.B. callbacks don't take const refs as mID is local scope)
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ registrar.add("TeleportHistory.TabOpen", boost::bind(&LLTeleportHistoryPanel::onAccordionTabOpen, this, tab));
+ registrar.add("TeleportHistory.TabClose", boost::bind(&LLTeleportHistoryPanel::onAccordionTabClose, this, tab));
+
+ // create the context menu from the XUI
+ mAccordionTabMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+ "menu_teleport_history_tab.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+
+ mAccordionTabMenu->setItemVisible("TabOpen", !tab->isExpanded() ? true : false);
+ mAccordionTabMenu->setItemVisible("TabClose", tab->isExpanded() ? true : false);
+
+ mAccordionTabMenu->show(x, y);
+ LLMenuGL::showPopup(tab, mAccordionTabMenu, x, y);
+}
+
+void LLTeleportHistoryPanel::onAccordionTabOpen(LLAccordionCtrlTab *tab)
+{
+ tab->setDisplayChildren(true);
+ mHistoryAccordion->arrange();
+}
+
+void LLTeleportHistoryPanel::onAccordionTabClose(LLAccordionCtrlTab *tab)
+{
+ tab->setDisplayChildren(false);
+ mHistoryAccordion->arrange();
+}
+
LLFlatListView* LLTeleportHistoryPanel::getFlatListViewFromTab(LLAccordionCtrlTab *tab)
{
for (child_list_const_iter_t iter = tab->beginChild(); iter != tab->endChild(); iter++)
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
index 66187e69c6..ebba25cfa5 100644
--- a/indra/newview/llpanelteleporthistory.h
+++ b/indra/newview/llpanelteleporthistory.h
@@ -37,6 +37,7 @@
#include "llpanelplacestab.h"
#include "llteleporthistory.h"
+#include "llmenugl.h"
class LLTeleportHistoryStorage;
class LLAccordionCtrl;
@@ -46,6 +47,25 @@ class LLFlatListView;
class LLTeleportHistoryPanel : public LLPanelPlacesTab
{
public:
+ class ContextMenu
+ {
+ public:
+ ContextMenu();
+ void show(LLView* spawning_view, S32 index, S32 x, S32 y);
+
+ private:
+ LLContextMenu* createMenu();
+ void onTeleport();
+ void onInfo();
+ void onCopy();
+ void onMakeLandmark();
+
+ static void gotSLURLCallback(const std::string& slurl);
+
+ LLContextMenu* mMenu;
+ S32 mIndex;
+ };
+
LLTeleportHistoryPanel();
virtual ~LLTeleportHistoryPanel();
@@ -59,6 +79,9 @@ public:
private:
static void onDoubleClickItem(void* user_data);
+ void onAccordionTabRightClick(LLView *view, S32 x, S32 y, MASK mask);
+ void onAccordionTabOpen(LLAccordionCtrlTab *tab);
+ void onAccordionTabClose(LLAccordionCtrlTab *tab);
void showTeleportHistory();
void handleItemSelect(LLFlatListView* );
LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *);
@@ -70,6 +93,9 @@ private:
typedef LLDynamicArray<LLAccordionCtrlTab*> item_containers_t;
item_containers_t mItemContainers;
+
+ ContextMenu mContextMenu;
+ LLContextMenu* mAccordionTabMenu;
};
#endif //LL_LLPANELTELEPORTHISTORY_H
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 0ecdec65d6..19bb60b237 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -44,6 +44,7 @@
#include "llinventorymodel.h"
#include "llkeyboard.h"
#include "lllineeditor.h"
+#include "llhelp.h"
#include "llresmgr.h"
#include "llscrollbar.h"
@@ -103,7 +104,7 @@ const std::string HELLO_LSL =
" llSay(0, \"Touched.\");\n"
" }\n"
"}\n";
-const std::string HELP_LSL_URL = "http://wiki.secondlife.com/wiki/LSL_Portal";
+const std::string HELP_LSL_PORTAL_TOPIC = "LSL_Portal";
const std::string DEFAULT_SCRIPT_NAME = "New Script"; // *TODO:Translate?
const std::string DEFAULT_SCRIPT_DESC = "(No Description)"; // *TODO:Translate?
@@ -264,7 +265,6 @@ struct LLSECKeywordCompare
LLScriptEdCore::LLScriptEdCore(
const std::string& sample,
- const std::string& help_url,
const LLHandle<LLFloater>& floater_handle,
void (*load_callback)(void*),
void (*save_callback)(void*, BOOL),
@@ -274,7 +274,6 @@ LLScriptEdCore::LLScriptEdCore(
:
LLPanel(),
mSampleText(sample),
- mHelpURL(help_url),
mEditor( NULL ),
mLoadCallback( load_callback ),
mSaveCallback( save_callback ),
@@ -436,7 +435,7 @@ void LLScriptEdCore::initMenu()
menuItem = getChild<LLMenuItemCallGL>("Help...");
menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnHelp, this));
- menuItem = getChild<LLMenuItemCallGL>("LSL Wiki Help...");
+ menuItem = getChild<LLMenuItemCallGL>("Keyword Help...");
menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnDynamicHelp, this));
}
@@ -539,9 +538,12 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
mLiveHelpTimer.stop();
}
}
- else if (immediate)
+ else
{
- setHelpPage(LLStringUtil::null);
+ if (immediate)
+ {
+ setHelpPage(LLStringUtil::null);
+ }
}
}
@@ -557,6 +559,7 @@ void LLScriptEdCore::setHelpPage(const std::string& help_string)
if (!history_combo) return;
LLUIString url_string = gSavedSettings.getString("LSLHelpURL");
+
url_string.setArg("[LSL_STRING]", help_string);
addHelpItemToHistory(help_string);
@@ -647,69 +650,52 @@ bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLS
return false;
}
-// static
-bool LLScriptEdCore::onHelpWebDialog(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
-
- switch(option)
- {
- case 0:
- LLWeb::loadURL(notification["payload"]["help_url"]);
- break;
- default:
- break;
- }
- return false;
-}
-
void LLScriptEdCore::onBtnHelp()
{
- LLSD payload;
- payload["help_url"] = mHelpURL;
- LLNotifications::instance().add("WebLaunchLSLGuide", LLSD(), payload, onHelpWebDialog);
+ LLUI::sHelpImpl->showTopic(HELP_LSL_PORTAL_TOPIC);
}
void LLScriptEdCore::onBtnDynamicHelp()
{
LLFloater* live_help_floater = mLiveHelpHandle.get();
- if (live_help_floater)
- {
- live_help_floater->setFocus(TRUE);
- updateDynamicHelp(TRUE);
+ if (!live_help_floater)
+ {
+ live_help_floater = new LLFloater(LLSD());
+ LLUICtrlFactory::getInstance()->buildFloater(live_help_floater, "floater_lsl_guide.xml", NULL);
+ LLFloater* parent = dynamic_cast<LLFloater*>(getParent());
+ parent->addDependentFloater(live_help_floater, TRUE);
+ live_help_floater->childSetCommitCallback("lock_check", onCheckLock, this);
+ live_help_floater->childSetValue("lock_check", gSavedSettings.getBOOL("ScriptHelpFollowsCursor"));
+ live_help_floater->childSetCommitCallback("history_combo", onHelpComboCommit, this);
+ live_help_floater->childSetAction("back_btn", onClickBack, this);
+ live_help_floater->childSetAction("fwd_btn", onClickForward, this);
+
+ LLMediaCtrl* browser = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html");
+ browser->setAlwaysRefresh(TRUE);
+
+ LLComboBox* help_combo = live_help_floater->getChild<LLComboBox>("history_combo");
+ LLKeywordToken *token;
+ LLKeywords::keyword_iterator_t token_it;
+ for (token_it = mEditor->keywordsBegin();
+ token_it != mEditor->keywordsEnd();
+ ++token_it)
+ {
+ token = token_it->second;
+ help_combo->add(wstring_to_utf8str(token->getToken()));
+ }
+ help_combo->sortByName();
- return;
+ // re-initialize help variables
+ mLastHelpToken = NULL;
+ mLiveHelpHandle = live_help_floater->getHandle();
+ mLiveHelpHistorySize = 0;
}
- live_help_floater = new LLFloater(LLSD());
- LLUICtrlFactory::getInstance()->buildFloater(live_help_floater, "floater_lsl_guide.xml", NULL);
- LLFloater* parent = dynamic_cast<LLFloater*>(getParent());
- parent->addDependentFloater(live_help_floater, TRUE);
- live_help_floater->childSetCommitCallback("lock_check", onCheckLock, this);
- live_help_floater->childSetValue("lock_check", gSavedSettings.getBOOL("ScriptHelpFollowsCursor"));
- live_help_floater->childSetCommitCallback("history_combo", onHelpComboCommit, this);
- live_help_floater->childSetAction("back_btn", onClickBack, this);
- live_help_floater->childSetAction("fwd_btn", onClickForward, this);
-
- LLMediaCtrl* browser = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html");
- browser->setAlwaysRefresh(TRUE);
-
- LLComboBox* help_combo = live_help_floater->getChild<LLComboBox>("history_combo");
- LLKeywordToken *token;
- LLKeywords::keyword_iterator_t token_it;
- for (token_it = mEditor->keywordsBegin();
- token_it != mEditor->keywordsEnd();
- ++token_it)
- {
- token = token_it->second;
- help_combo->add(wstring_to_utf8str(token->getToken()));
- }
- help_combo->sortByName();
+ BOOL visible = TRUE;
+ BOOL take_focus = TRUE;
+ live_help_floater->setVisible(visible);
+ live_help_floater->setFrontmost(take_focus);
- // re-initialize help variables
- mLastHelpToken = NULL;
- mLiveHelpHandle = live_help_floater->getHandle();
- mLiveHelpHistorySize = 0;
updateDynamicHelp(TRUE);
}
@@ -945,7 +931,6 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata)
self->mScriptEd = new LLScriptEdCore(
HELLO_LSL,
- HELP_LSL_URL,
self->getHandle(),
LLPreviewLSL::onLoad,
LLPreviewLSL::onSave,
@@ -1411,7 +1396,6 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata)
self->mScriptEd = new LLScriptEdCore(
HELLO_LSL,
- HELP_LSL_URL,
self->getHandle(),
&LLLiveLSLEditor::onLoad,
&LLLiveLSLEditor::onSave,
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 623886101a..a00f580e32 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -64,7 +64,6 @@ class LLScriptEdCore : public LLPanel
public:
LLScriptEdCore(
const std::string& sample,
- const std::string& help_url,
const LLHandle<LLFloater>& floater_handle,
void (*load_callback)(void* userdata),
void (*save_callback)(void* userdata, BOOL close_after_save),
@@ -86,7 +85,6 @@ public:
bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response);
bool handleReloadFromServerDialog(const LLSD& notification, const LLSD& response);
- static bool onHelpWebDialog(const LLSD& notification, const LLSD& response);
static void onCheckLock(LLUICtrl*, void*);
static void onHelpComboCommit(LLUICtrl* ctrl, void* userdata);
static void onClickBack(void* userdata);
@@ -116,7 +114,6 @@ protected:
private:
std::string mSampleText;
- std::string mHelpURL;
LLTextEditor* mEditor;
void (*mLoadCallback)(void* userdata);
void (*mSaveCallback)(void* userdata, BOOL close_after_save);
@@ -124,7 +121,6 @@ private:
void* mUserdata;
LLComboBox *mFunctions;
BOOL mForceClose;
- //LLPanel* mGuiPanel;
LLPanel* mCodePanel;
LLScrollListCtrl* mErrorList;
LLDynamicArray<LLEntryAndEdCore*> mBridges;
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 082bba027f..8a96a5a1ae 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -55,36 +55,30 @@ using namespace LLNotificationsUI;
bool LLScreenChannel::mWasStartUpToastShown = false;
//--------------------------------------------------------------------------
-LLScreenChannel::LLScreenChannel(LLUUID& id): mOverflowToastPanel(NULL), mStartUpToastPanel(NULL),
- mToastAlignment(NA_BOTTOM), mCanStoreToasts(true),
- mHiddenToastsNum(0), mOverflowToastHidden(false),
- mIsHovering(false), mControlHovering(false),
- mShowToasts(true)
+//////////////////////
+// LLScreenChannelBase
+//////////////////////
+LLScreenChannelBase::LLScreenChannelBase(const LLUUID& id) :
+ mOverflowToastPanel(NULL)
+ ,mToastAlignment(NA_BOTTOM)
+ ,mCanStoreToasts(true)
+ ,mHiddenToastsNum(0)
+ ,mOverflowToastHidden(false)
+ ,mIsHovering(false)
+ ,mControlHovering(false)
+ ,mShowToasts(true)
{
mID = id;
mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString");
- mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannel::updatePositionAndSize, this, _1, _2));
+ mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2));
setMouseOpaque( false );
setVisible(FALSE);
}
-
-//--------------------------------------------------------------------------
-void LLScreenChannel::init(S32 channel_left, S32 channel_right)
-{
- S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
- S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
- setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
- setVisible(TRUE);
-}
-
-//--------------------------------------------------------------------------
-LLScreenChannel::~LLScreenChannel()
+LLScreenChannelBase::~LLScreenChannelBase()
{
mWorldViewRectConnection.disconnect();
}
-
-//--------------------------------------------------------------------------
-void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
+void LLScreenChannelBase::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
{
S32 top_delta = old_world_rect.mTop - new_world_rect.mTop;
S32 right_delta = old_world_rect.mRight - new_world_rect.mRight;
@@ -105,6 +99,42 @@ void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_wo
}
setRect(this_rect);
redrawToasts();
+
+}
+
+void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
+{
+ S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
+ S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
+ setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
+ setVisible(TRUE);
+}
+
+//--------------------------------------------------------------------------
+//////////////////////
+// LLScreenChannel
+//////////////////////
+//--------------------------------------------------------------------------
+LLScreenChannel::LLScreenChannel(LLUUID& id): LLScreenChannelBase(id)
+{
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::init(S32 channel_left, S32 channel_right)
+{
+ LLScreenChannelBase::init(channel_left, channel_right);
+}
+
+//--------------------------------------------------------------------------
+LLScreenChannel::~LLScreenChannel()
+{
+
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
+{
+ LLScreenChannelBase::updatePositionAndSize(old_world_rect, new_world_rect);
}
//--------------------------------------------------------------------------
@@ -112,7 +142,7 @@ void LLScreenChannel::addToast(LLToast::Params p)
{
bool store_toast = false, show_toast = false;
- show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
+ mDisplayToastsAlways ? show_toast = true : show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
store_toast = !show_toast && p.can_be_stored && mCanStoreToasts;
if(!show_toast && !store_toast)
@@ -561,7 +591,7 @@ void LLScreenChannel::removeAndStoreAllStorableToasts()
else
{
++it;
- }
+ }
}
redrawToasts();
}
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index f1ef6bd64d..459c28ac7c 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -55,10 +55,95 @@ typedef enum e_channel_alignment
CA_RIGHT,
} EChannelAlignment;
+class LLScreenChannelBase : public LLUICtrl
+{
+ friend class LLChannelManager;
+public:
+ LLScreenChannelBase(const LLUUID& id);
+ ~LLScreenChannelBase();
+
+ // Channel's outfit-functions
+ // update channel's size and position in the World View
+ virtual void updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
+ // initialization of channel's shape and position
+ virtual void init(S32 channel_left, S32 channel_right);
+
+
+ virtual void setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
+
+ virtual void setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
+ virtual void setOverflowFormatString ( const std::string& str) { mOverflowFormatString = str; }
+
+ // kill or modify a toast by its ID
+ virtual void killToastByNotificationID(LLUUID id) {};
+ virtual void modifyToastNotificationByID(LLUUID id, LLSD data) {};
+
+ // hide all toasts from screen, but not remove them from a channel
+ virtual void hideToastsFromScreen() {};
+ // removes all toasts from a channel
+ virtual void removeToastsFromChannel() {};
+
+ // show all toasts in a channel
+ virtual void redrawToasts() {};
+
+ virtual void closeOverflowToastPanel() {};
+ virtual void hideOverflowToastPanel() {};
+
+
+ // Channel's behavior-functions
+ // set whether a channel will control hovering inside itself or not
+ virtual void setControlHovering(bool control) { mControlHovering = control; }
+ // set Hovering flag for a channel
+ virtual void setHovering(bool hovering) { mIsHovering = hovering; }
+
+ void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
+
+ void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
+ bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
+
+ // get number of hidden notifications from a channel
+ S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;}
+
+
+ void setShowToasts(bool show) { mShowToasts = show; }
+ bool getShowToasts() { return mShowToasts; }
+
+ // get toast allignment preset for a channel
+ e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
+
+ // get ID of a channel
+ LLUUID getChannelID() { return mID; }
+
+protected:
+ // Channel's flags
+ bool mControlHovering;
+ bool mIsHovering;
+ bool mCanStoreToasts;
+ bool mDisplayToastsAlways;
+ bool mOverflowToastHidden;
+ // controls whether a channel shows toasts or not
+ bool mShowToasts;
+ //
+ EToastAlignment mToastAlignment;
+ EChannelAlignment mChannelAlignment;
+
+ // attributes for the Overflow Toast
+ S32 mHiddenToastsNum;
+ LLToast* mOverflowToastPanel;
+ std::string mOverflowFormatString;
+
+ // channel's ID
+ LLUUID mID;
+
+ // store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
+ boost::signals2::connection mWorldViewRectConnection;
+};
+
+
/**
* Screen channel manages toasts visibility and positioning on the screen.
*/
-class LLScreenChannel : public LLUICtrl
+class LLScreenChannel : public LLScreenChannelBase
{
friend class LLChannelManager;
public:
@@ -70,12 +155,6 @@ public:
void updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
// initialization of channel's shape and position
void init(S32 channel_left, S32 channel_right);
- // set allignment of toasts inside a channel
- void setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
- // set allignment of channel inside a world view
- void setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
- // set a template for a string in the OverflowToast
- void setOverflowFormatString ( std::string str) { mOverflowFormatString = str; }
// Operating with toasts
// add a toast to a channel
@@ -104,37 +183,17 @@ public:
// close the StartUp Toast
void closeStartUpToast();
- // Channel's behavior-functions
- // set whether a channel will control hovering inside itself or not
- void setControlHovering(bool control) { mControlHovering = control; }
- // set Hovering flag for a channel
- void setHovering(bool hovering) { mIsHovering = hovering; }
- // set whether a channel will store faded toasts or not
- void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
- // tell all channels that the StartUp toast was shown and allow them showing of toasts
- static void setStartUpToastShown() { mWasStartUpToastShown = true; }
// get StartUp Toast's state
static bool getStartUpToastShown() { return mWasStartUpToastShown; }
- // set mode for dislaying of toasts
- void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
- // get mode for dislaying of toasts
- bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
- // tell a channel to show toasts or not
- void setShowToasts(bool show) { mShowToasts = show; }
- // determine whether channel shows toasts or not
- bool getShowToasts() { return mShowToasts; }
+ // tell all channels that the StartUp toast was shown and allow them showing of toasts
+ static void setStartUpToastShown() { mWasStartUpToastShown = true; }
// let a channel update its ShowToast flag
void updateShowToastsState();
+
// Channel's other interface functions functions
- // get number of hidden notifications from a channel
- S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;}
// update number of notifications in the StartUp Toast
void updateStartUpString(S32 num);
- // get toast allignment preset for a channel
- e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
- // get ID of a channel
- LLUUID getChannelID() { return mID; }
// Channel's signals
// signal on storing of faded toasts event
@@ -201,30 +260,10 @@ private:
// Channel's flags
static bool mWasStartUpToastShown;
- bool mControlHovering;
- bool mIsHovering;
- bool mCanStoreToasts;
- bool mDisplayToastsAlways;
- bool mOverflowToastHidden;
- // controls whether a channel shows toasts or not
- bool mShowToasts;
- //
- EToastAlignment mToastAlignment;
- EChannelAlignment mChannelAlignment;
-
- // attributes for the Overflow Toast
- S32 mHiddenToastsNum;
- LLToast* mOverflowToastPanel;
- std::string mOverflowFormatString;
// attributes for the StartUp Toast
LLToast* mStartUpToastPanel;
- // channel's ID
- LLUUID mID;
-
- // store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
- boost::signals2::connection mWorldViewRectConnection;
std::vector<ToastElem> mToastList;
std::vector<ToastElem> mStoredToastList;
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index b25331e439..ae8c9f770b 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1721,13 +1721,8 @@ void LLSelectMgr::selectionSetFullbright(U8 fullbright)
getSelection()->applyToObjects(&sendfunc);
}
-void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url)
+void LLSelectMgr::selectionSetMedia(U8 media_type)
{
- U8 media_flags = LLTextureEntry::MF_NONE;
- if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE)
- {
- media_flags = LLTextureEntry::MF_WEB_PAGE;
- }
struct f : public LLSelectedTEFunctor
{
@@ -1737,33 +1732,72 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string&
{
if (object->permModify())
{
- // update viewer side color in anticipation of update from simulator
+ // update viewer has media
object->setTEMediaFlags(te, mMediaFlags);
}
return true;
}
- } setfunc(media_flags);
+ } setfunc(media_type);
getSelection()->applyToTEs(&setfunc);
-
- struct g : public LLSelectedObjectFunctor
+ struct f2 : public LLSelectedObjectFunctor
{
- U8 media_type;
- const std::string& media_url ;
- g(U8 a, const std::string& b) : media_type(a), media_url(b) {}
virtual bool apply(LLViewerObject* object)
{
if (object->permModify())
{
object->sendTEUpdate();
- object->setMediaType(media_type);
- object->setMediaURL(media_url);
}
return true;
}
- } sendfunc(media_type, media_url);
- getSelection()->applyToObjects(&sendfunc);
+ } func2;
+ mSelectedObjects->applyToObjects( &func2 );
}
+// This function expects media_data to be a map containing relevant
+// media data name/value pairs (e.g. home_url, etc.)
+void LLSelectMgr::selectionSetMediaData(const LLSD &media_data)
+{
+
+ struct f : public LLSelectedTEFunctor
+ {
+ const LLSD &mMediaData;
+ f(const LLSD& t) : mMediaData(t) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
+ if (NULL != vo)
+ {
+ vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/);
+ }
+ }
+ return true;
+ }
+ } setfunc(media_data);
+ getSelection()->applyToTEs(&setfunc);
+
+ struct f2 : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
+ if (NULL != vo)
+ {
+ // Send updated media data FOR THE ENTIRE OBJECT
+ vo->sendMediaDataUpdate();
+ }
+ }
+ return true;
+ }
+ } func2;
+ getSelection()->applyToObjects(&func2);
+}
+
+
+
void LLSelectMgr::selectionSetGlow(F32 glow)
{
struct f1 : public LLSelectedTEFunctor
@@ -5057,7 +5091,15 @@ void LLSelectNode::selectTE(S32 te_index, BOOL selected)
{
return;
}
- mTESelectMask |= 0x1 << te_index;
+ S32 mask = 0x1 << te_index;
+ if(selected)
+ {
+ mTESelectMask |= mask;
+ }
+ else
+ {
+ mTESelectMask &= ~mask;
+ }
mLastTESelected = te_index;
}
@@ -6042,6 +6084,29 @@ bool LLObjectSelection::applyToRootNodes(LLSelectedNodeFunctor *func, bool first
return result;
}
+BOOL LLObjectSelection::isMultipleTESelected()
+{
+ BOOL te_selected = FALSE;
+ // ...all faces
+ for (LLObjectSelection::iterator iter = begin();
+ iter != end(); iter++)
+ {
+ LLSelectNode* nodep = *iter;
+ for (S32 i = 0; i < SELECT_MAX_TES; i++)
+ {
+ if(nodep->isTESelected(i))
+ {
+ if(te_selected)
+ {
+ return TRUE;
+ }
+ te_selected = TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
//-----------------------------------------------------------------------------
// contains()
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 08c2783746..9e02170d74 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -307,6 +307,7 @@ public:
S32 getTECount();
S32 getRootObjectCount();
+ BOOL isMultipleTESelected();
BOOL contains(LLViewerObject* object);
BOOL contains(LLViewerObject* object, S32 te);
@@ -504,7 +505,8 @@ public:
void selectionSetTexGen( U8 texgen );
void selectionSetShiny( U8 shiny );
void selectionSetFullbright( U8 fullbright );
- void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url );
+ void selectionSetMedia( U8 media_type );
+ void selectionSetMediaData(const LLSD &media_data); // NOTE: modifies media_data!!!
void selectionSetClickAction(U8 action);
void selectionSetIncludeInSearch(bool include_in_search);
void selectionSetGlow(const F32 glow);
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 381e63f020..2be0aa40d2 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -48,6 +48,7 @@
#include "lliconctrl.h"//for Home tab icon
#include "llsidetraypanelcontainer.h"
#include "llwindow.h"//for SetCursor
+#include "lltransientfloatermgr.h"
//#include "llscrollcontainer.h"
@@ -248,6 +249,7 @@ LLSideTray::LLSideTray(Params& params)
// register handler function to process data from the xml.
// panel_name should be specified via "parameter" attribute.
commit.add("SideTray.ShowPanel", boost::bind(&LLSideTray::showPanel, this, _2, LLUUID::null));
+ LLTransientFloaterMgr::getInstance()->addControlView(this);
}
@@ -448,13 +450,17 @@ void LLSideTray::reflectCollapseChange()
setPanelRect();
if(mCollapsed)
+ {
gFloaterView->setSnapOffsetRight(0);
+ setFocus(FALSE);
+ }
else
+ {
gFloaterView->setSnapOffsetRight(mMaxBarWidth);
+ setFocus(TRUE);
+ }
gFloaterView->refresh();
-
- setFocus( FALSE );
}
void LLSideTray::arrange ()
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 4e13cb17a2..7bf0d31d94 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -433,6 +433,11 @@ void LLSpatialGroup::clearDrawMap()
mDrawMap.clear();
}
+BOOL LLSpatialGroup::isRecentlyVisible() const
+{
+ return (LLDrawable::getCurrentFrame() - (S32)mVisible) < LLDrawable::getMinVisFrameRange() ;
+}
+
BOOL LLSpatialGroup::isVisible() const
{
return mVisible[LLViewerCamera::sCurCameraID] == LLDrawable::getCurrentFrame() ? TRUE : FALSE;
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 16e8782a8e..64c2a9acbc 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -267,6 +267,7 @@ public:
BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
BOOL isVisible() const;
+ BOOL isRecentlyVisible() const;
void setVisible();
void shift(const LLVector3 &offset);
BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 6a55b571ae..053b863b6d 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1429,6 +1429,17 @@ bool idle_startup()
LLStartUp::deletePasswordFromDisk();
}
+ // this is the base used to construct help URLs
+ text = LLUserAuth::getInstance()->getResponse("help_url_format");
+ if (!text.empty())
+ {
+ // replace the default help URL format
+ gSavedSettings.setString("HelpURLFormat",text);
+
+ // don't fall back to Nebraska's pre-connection static help
+ gSavedSettings.setBOOL("HelpUseLocal", false);
+ }
+
// this is their actual ability to access content
text = LLUserAuth::getInstance()->getResponse("agent_access_max");
if (!text.empty())
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index d7df258750..b0930cd86d 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -225,22 +225,14 @@ void LLStatusBar::draw()
BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- if (mHideNavbarContextMenu)
- {
- mHideNavbarContextMenu->buildDrawLabels();
- mHideNavbarContextMenu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, mHideNavbarContextMenu, x, y);
- }
-
+ show_navbar_context_menu(this,x,y);
return TRUE;
}
BOOL LLStatusBar::postBuild()
{
- mHideNavbarContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- gMenuHolder->addChild(mHideNavbarContextMenu);
- gMenuBarView->setRightMouseDownCallback(boost::bind(&LLStatusBar::onMainMenuRightClicked, this, _1, _2, _3, _4));
+ gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3));
return TRUE;
}
@@ -560,11 +552,6 @@ void LLStatusBar::setupDate()
}
}
-void LLStatusBar::onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
-{
- handleRightMouseDown(x, y, mask);
-}
-
// static
void LLStatusBar::onClickStatGraph(void* data)
{
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 81a69e9590..d5629e6f1e 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -91,7 +91,6 @@ private:
// simple method to setup the part that holds the date
void setupDate();
- void onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask);
static void onCommitSearch(LLUICtrl*, void* data);
static void onClickSearch(void* data);
static void onClickStatGraph(void* data);
@@ -111,8 +110,7 @@ private:
S32 mSquareMetersCommitted;
LLFrameTimer* mBalanceTimer;
LLFrameTimer* mHealthTimer;
- LLMenuGL* mHideNavbarContextMenu;
-
+
static std::vector<std::string> sDays;
static std::vector<std::string> sMonths;
static const U32 MAX_DATE_STRING_LENGTH;
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index c1eecf4c12..669d8d1d70 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -109,6 +109,15 @@ BOOL LLSysWellWindow::postBuild()
}
//---------------------------------------------------------------------------------
+void LLSysWellWindow::setMinimized(BOOL minimize)
+{
+ // we don't show empty Message Well window
+ setVisible(!minimize && !isWindowEmpty());
+
+ LLFloater::setMinimized(minimize);
+}
+
+//---------------------------------------------------------------------------------
void LLSysWellWindow::connectListUpdaterToSignal(std::string notification_type)
{
LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
@@ -155,10 +164,10 @@ void LLSysWellWindow::addItem(LLSysWellItem::Params p)
{
handleItemAdded(IT_NOTIFICATION);
- reshapeWindow();
+ reshapeWindow();
- new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
- new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
+ new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
+ new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
}
else
{
@@ -226,11 +235,11 @@ void LLSysWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
//---------------------------------------------------------------------------------
void LLSysWellWindow::initChannel()
{
- LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
+ LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
- if(channel)
+ mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
+ if(mChannel)
{
- mChannel = channel;
mChannel->setOnStoreToastCallback(boost::bind(&LLSysWellWindow::onStoreToast, this, _1, _2));
}
else
@@ -240,7 +249,7 @@ void LLSysWellWindow::initChannel()
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::getEnabledRect(LLRect& rect)
+void LLSysWellWindow::getAllowedRect(LLRect& rect)
{
rect = gViewerWindow->getWorldViewRect();
}
@@ -252,7 +261,7 @@ void LLSysWellWindow::toggleWindow()
{
setDockControl(new LLDockControl(
LLBottomTray::getInstance()->getSysWell(), this,
- getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getEnabledRect, this, _1)));
+ getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getAllowedRect, this, _1)));
}
if(!getVisible())
@@ -404,20 +413,18 @@ bool LLSysWellWindow::isWindowEmpty()
//---------------------------------------------------------------------------------
//virtual
-void LLSysWellWindow::sessionAdded(const LLUUID& sessionId,
- const std::string& name, const LLUUID& otherParticipantId)
+void LLSysWellWindow::sessionAdded(const LLUUID& session_id,
+ const std::string& name, const LLUUID& other_participant_id)
{
- if (mMessageList->getItemByValue(get_session_value(sessionId)) == NULL)
+ //*TODO get rid of get_session_value, session_id's are unique, cause performance degradation with lots chiclets (IB)
+ if (mMessageList->getItemByValue(get_session_value(session_id)) == NULL)
{
- S32 chicletCounter = 0;
- LLIMModel::LLIMSession* session = get_if_there(LLIMModel::sSessionsMap,
- sessionId, (LLIMModel::LLIMSession*) NULL);
- if (session != NULL)
+ S32 chicletCounter = LLIMModel::getInstance()->getNumUnread(session_id);
+ if (chicletCounter > -1)
{
- chicletCounter = session->mNumUnread;
+ addIMRow(session_id, chicletCounter, name, other_participant_id);
+ reshapeWindow();
}
- addIMRow(sessionId, chicletCounter, name, otherParticipantId);
- reshapeWindow();
}
}
@@ -491,6 +498,7 @@ LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID&
switch (im_chiclet_type)
{
case LLIMChiclet::TYPE_GROUP:
+ case LLIMChiclet::TYPE_AD_HOC:
mChiclet = getChild<LLIMChiclet>("group_chiclet");
childSetVisible("p2p_chiclet", false);
break;
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 37a2690a82..203b949715 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -68,6 +68,8 @@ public:
void toggleWindow();
/*virtual*/ BOOL canClose() { return FALSE; }
/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
+ // override LLFloater's minimization according to EXT-1216
+ /*virtual*/ void setMinimized(BOOL minimize);
// Handlers
void onItemClick(LLSysWellItem* item);
@@ -86,8 +88,8 @@ private:
IT_INSTANT_MESSAGE
}EItemType;
- // gets a rect valid for SysWellWindow's position on a screen (EXT-1111)
- void getEnabledRect(LLRect& rect);
+ // gets a rect that bounds possible positions for the SysWellWindow on a screen (EXT-1111)
+ void getAllowedRect(LLRect& rect);
// connect counter and list updaters to the corresponding signals
void connectListUpdaterToSignal(std::string notification_type);
// init Window's channel
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 97a15759bf..84931e4d2d 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -41,7 +41,7 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLToast::LLToast(LLToast::Params p) : LLFloater(LLSD()),
+LLToast::LLToast(LLToast::Params p) : LLModalDialog(LLSD(), p.is_modal),
mPanel(p.panel),
mTimerValue(p.timer_period),
mNotificationID(p.notif_id),
@@ -49,7 +49,6 @@ LLToast::LLToast(LLToast::Params p) : LLFloater(LLSD()),
mCanFade(p.can_fade),
mCanBeStored(p.can_be_stored),
mHideBtnEnabled(p.enable_hide_btn),
- mIsModal(p.is_modal),
mHideBtn(NULL),
mNotification(p.notification),
mHideBtnPressed(false)
@@ -67,13 +66,6 @@ LLToast::LLToast(LLToast::Params p) : LLFloater(LLSD()),
mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this));
}
- if(mIsModal)
- {
- gFocusMgr.setMouseCapture( this );
- gFocusMgr.setTopCtrl( this );
- setFocus(TRUE);
- }
-
// init callbacks if present
if(!p.on_delete_toast.empty())
mOnDeleteToastSignal.connect(p.on_delete_toast);
@@ -104,11 +96,6 @@ void LLToast::setHideButtonEnabled(bool enabled)
LLToast::~LLToast()
{
mOnToastDestroyedSignal(this);
- if(mIsModal)
- {
- gFocusMgr.unlockFocus();
- gFocusMgr.releaseFocusIfNeeded( this );
- }
}
//--------------------------------------------------------------------------
@@ -167,15 +154,30 @@ void LLToast::tick()
}
//--------------------------------------------------------------------------
-void LLToast::insertPanel(LLPanel* panel)
+
+void LLToast::reshapeToPanel()
{
- LLRect panel_rect, toast_rect;
+ LLPanel* panel = getPanel();
+ if(!panel)
+ return;
+
+ LLRect panel_rect;
panel_rect = panel->getRect();
reshape(panel_rect.getWidth(), panel_rect.getHeight());
panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight());
panel->setRect(panel_rect);
+
+ LLRect toast_rect = getRect();
+ toast_rect.setLeftTopAndSize(toast_rect.mLeft,toast_rect.mTop,panel_rect.getWidth(), panel_rect.getHeight());
+ setRect(toast_rect);
+
+}
+
+void LLToast::insertPanel(LLPanel* panel)
+{
addChild(panel);
+ reshapeToPanel();
}
//--------------------------------------------------------------------------
@@ -190,18 +192,6 @@ void LLToast::draw()
}
//--------------------------------------------------------------------------
-void LLToast::setModal(bool modal)
-{
- mIsModal = modal;
- if(mIsModal)
- {
- gFocusMgr.setMouseCapture( this );
- gFocusMgr.setTopCtrl( this );
- setFocus(TRUE);
- }
-}
-
-//--------------------------------------------------------------------------
void LLToast::setVisible(BOOL show)
{
if(show)
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 9248747c43..29c231a01d 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -35,7 +35,7 @@
#include "llpanel.h"
-#include "llfloater.h"
+#include "llmodaldialog.h"
#include "lltimer.h"
#include "llnotifications.h"
@@ -51,7 +51,7 @@ namespace LLNotificationsUI
* Represents toast pop-up.
* This is a parent view for all toast panels.
*/
-class LLToast : public LLFloater
+class LLToast : public LLModalDialog
{
public:
typedef boost::function<void (LLToast* toast)> toast_callback_t;
@@ -99,6 +99,9 @@ public:
// Operating with toasts
// insert a panel to a toast
void insertPanel(LLPanel* panel);
+
+ void reshapeToPanel();
+
// get toast's panel
LLPanel* getPanel() { return mPanel; }
// enable/disable Toast's Hide button
@@ -131,8 +134,6 @@ public:
void setCanBeStored(bool can_be_stored) { mCanBeStored = can_be_stored; }
//
bool getCanBeStored() { return mCanBeStored; }
- //
- void setModal(bool modal);
// Registers signals/callbacks for events
@@ -168,7 +169,6 @@ private:
LLColor4 mBgColor;
bool mCanFade;
- bool mIsModal;
bool mCanBeStored;
bool mHideBtnEnabled;
bool mHideBtnPressed;
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index bc9888f4b4..418373e8c6 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -39,6 +39,12 @@
#include <string>
+class LLToastPanelBase: public LLPanel
+{
+public:
+ virtual void init(LLSD& data){};
+};
+
/**
* Base class for all panels that can be added to the toast.
* All toast panels should contain necessary logic for representing certain notification
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index ceb1358d1c..880d5d5e12 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -67,18 +67,20 @@ LLTool::~LLTool()
BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
{
- // This is necessary to force clicks in the world to cause edit
- // boxes that might have keyboard focus to relinquish it, and hence
- // cause a commit to update their value. JC
- if (down)
+ BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
+
+ // This behavior was moved here from LLViewerWindow::handleAnyMouseClick, so it can be selectively overridden by LLTool subclasses.
+ if(down && result)
{
+ // This is necessary to force clicks in the world to cause edit
+ // boxes that might have keyboard focus to relinquish it, and hence
+ // cause a commit to update their value. JC
gFocusMgr.setKeyboardFocus(NULL);
}
-
- return LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
+
+ return result;
}
-
BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (gDebugClicks)
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 5c210c5c28..d5db224143 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -48,6 +48,7 @@
#include "lltooltip.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
+#include "llmediaentry.h"
#include "llmenugl.h"
#include "llmutelist.h"
#include "llselectmgr.h"
@@ -75,8 +76,6 @@ extern void handle_buy(void*);
extern BOOL gDebugClicks;
-static bool handle_media_click(const LLPickInfo& info);
-static bool handle_media_hover(const LLPickInfo& info);
static void handle_click_action_play();
static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp);
static ECursorType cursor_from_parcel_media(U8 click_action);
@@ -90,6 +89,16 @@ LLToolPie::LLToolPie()
{ }
+BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
+{
+ BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
+
+ // This override DISABLES the keyboard focus reset that LLTool::handleAnyMouseClick adds.
+ // LLToolPie will do the right thing in its pick callback.
+
+ return result;
+}
+
BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
{
//left mouse down always picks transparent
@@ -258,9 +267,9 @@ BOOL LLToolPie::pickLeftMouseDownCallback()
}
}
- if (handle_media_click(mPick))
+ if (handleMediaClick(mPick))
{
- return FALSE;
+ return TRUE;
}
// put focus back "in world"
@@ -466,10 +475,7 @@ void LLToolPie::selectionPropertiesReceived()
BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
{
mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE);
-
- // FIXME: This was in the pluginapi branch, but I don't think it's correct.
-// gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
-
+
LLViewerObject *parent = NULL;
LLViewerObject *object = mHoverPick.getObject();
@@ -484,7 +490,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
gViewerWindow->setCursor(cursor);
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
}
- else if (handle_media_hover(mHoverPick))
+ else if (handleMediaHover(mHoverPick))
{
// cursor set by media object
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
@@ -522,6 +528,9 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
{
LLViewerObject* obj = mPick.getObject();
+
+ handleMediaMouseUp();
+
U8 click_action = final_click_action(obj);
if (click_action != CLICK_ACTION_NONE)
{
@@ -543,6 +552,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
break;
}
}
+
mGrabMouseButtonDown = FALSE;
LLToolMgr::getInstance()->clearTransientTool();
gAgent.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on
@@ -1038,6 +1048,7 @@ void LLToolPie::stopEditing()
void LLToolPie::onMouseCaptureLost()
{
mMouseOutsideSlop = FALSE;
+ handleMediaMouseUp();
}
@@ -1078,7 +1089,7 @@ static void handle_click_action_play()
}
}
-static bool handle_media_click(const LLPickInfo& pick)
+bool LLToolPie::handleMediaClick(const LLPickInfo& pick)
{
//FIXME: how do we handle object in different parcel than us?
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
@@ -1104,22 +1115,25 @@ static bool handle_media_click(const LLPickInfo& pick)
// is media playing on this face?
const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
+ LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL;
+ viewer_media_t media_impl = mep ? LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()) : NULL;
- viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
- if (tep
- && media_impl.notNull()
- && media_impl->hasMedia()
- && gSavedSettings.getBOOL("MediaOnAPrimUI"))
+ if (tep
+ && mep
+ && gSavedSettings.getBOOL("MediaOnAPrimUI")
+ && media_impl.notNull())
{
- LLObjectSelectionHandle selection = LLViewerMediaFocus::getInstance()->getSelection();
- if (! selection->contains(pick.getObject(), pick.mObjectFace))
+ // LLObjectSelectionHandle selection = /*LLViewerMediaFocus::getInstance()->getSelection()*/ LLSelectMgr::getInstance()->getSelection();
+ if (/*! selection->contains(pick.getObject(), pick.mObjectFace)*/
+ ! LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) )
{
LLViewerMediaFocus::getInstance()->setFocusFace(TRUE, pick.getObject(), pick.mObjectFace, media_impl);
}
else
{
- media_impl->mouseDown(pick.mXYCoords.mX, pick.mXYCoords.mY);
- media_impl->mouseCapture(); // the mouse-up will happen when capture is lost
+ media_impl->mouseDown(pick.mUVCoords);
+ mMediaMouseCaptureID = mep->getMediaID();
+ setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture.
}
return true;
@@ -1131,7 +1145,7 @@ static bool handle_media_click(const LLPickInfo& pick)
return false;
}
-static bool handle_media_hover(const LLPickInfo& pick)
+bool LLToolPie::handleMediaHover(const LLPickInfo& pick)
{
//FIXME: how do we handle object in different parcel than us?
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
@@ -1156,15 +1170,20 @@ static bool handle_media_hover(const LLPickInfo& pick)
// is media playing on this face?
const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
- viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
- if (tep
- && media_impl.notNull()
- && media_impl->hasMedia()
+ const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
+ if (mep
&& gSavedSettings.getBOOL("MediaOnAPrimUI"))
- {
- if(LLViewerMediaFocus::getInstance()->getFocus())
+ {
+ viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
+ if(LLViewerMediaFocus::getInstance()->getFocus() && media_impl.notNull())
{
- media_impl->mouseMove(pick.mXYCoords.mX, pick.mXYCoords.mY);
+ media_impl->mouseMove(pick.mUVCoords);
+
+ gViewerWindow->setCursor(media_impl->getLastSetCursor());
+ }
+ else
+ {
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
}
// Set mouse over flag if unset
@@ -1182,6 +1201,28 @@ static bool handle_media_hover(const LLPickInfo& pick)
return false;
}
+bool LLToolPie::handleMediaMouseUp()
+{
+ bool result = false;
+ if(mMediaMouseCaptureID.notNull())
+ {
+ // Face media needs to know the mouse went up.
+ viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mMediaMouseCaptureID);
+ if(media_impl)
+ {
+ // This will send a mouseUp event to the plugin using the last known mouse coordinate (from a mouseDown or mouseMove), which is what we want.
+ media_impl->onMouseCaptureLost();
+ }
+
+ mMediaMouseCaptureID.setNull();
+
+ setMouseCapture(FALSE);
+
+ result = true;
+ }
+
+ return result;
+}
static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp)
{
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 328653d2b8..f6a67c13b1 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -42,9 +42,12 @@ class LLObjectSelection;
class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
{
+ LOG_CLASS(LLToolPie);
public:
LLToolPie( );
+ // Virtual functions inherited from LLMouseHandler
+ virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@@ -81,9 +84,15 @@ private:
BOOL useClickAction (MASK mask, LLViewerObject* object,LLViewerObject* parent);
void showVisualContextMenuEffect();
+
+ bool handleMediaClick(const LLPickInfo& info);
+ bool handleMediaHover(const LLPickInfo& info);
+ bool handleMediaMouseUp();
+
private:
BOOL mGrabMouseButtonDown;
BOOL mMouseOutsideSlop; // for this drag, has mouse moved outside slop region
+ LLUUID mMediaMouseCaptureID;
LLPickInfo mPick;
LLPickInfo mHoverPick;
LLPointer<LLViewerObject> mClickActionObject;
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 901d0594f1..e7a8ad6605 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -37,7 +37,7 @@
#include "llagent.h" // teleportViaLocation()
#include "llcommandhandler.h"
#include "llfloaterdirectory.h"
-#include "llfloatermediabrowser.h"
+#include "llfloaterhelpbrowser.h"
#include "llfloaterreg.h"
#include "llfloaterurldisplay.h"
#include "llfloaterworldmap.h"
@@ -105,7 +105,7 @@ bool LLURLDispatcherImpl::dispatchCore(const std::string& url,
bool trusted_browser)
{
if (url.empty()) return false;
- if (dispatchHelp(url, right_mouse)) return true;
+ //if (dispatchHelp(url, right_mouse)) return true;
if (dispatchApp(url, right_mouse, web, trusted_browser)) return true;
if (dispatchRegion(url, right_mouse)) return true;
@@ -140,19 +140,6 @@ bool LLURLDispatcherImpl::dispatchRightClick(const std::string& url)
}
// static
-bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, bool right_mouse)
-{
-#if LL_LIBXUL_ENABLED
- if (LLSLURL::isURLHelp(url))
- {
- gViewerHtmlHelp.show();
- return true;
- }
-#endif
- return false;
-}
-
-// static
bool LLURLDispatcherImpl::dispatchApp(const std::string& url,
bool right_mouse,
LLMediaCtrl* web,
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 51d699c0f7..2f656479f6 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -65,8 +65,9 @@
#include "llfloatergodtools.h"
#include "llfloatergroups.h"
#include "llfloaterhardwaresettings.h"
-#include "llfloaterhtmlcurrency.h"
+#include "llfloaterhelpbrowser.h"
#include "llfloatermediabrowser.h"
+#include "llfloatermediasettings.h"
#include "llfloaterhud.h"
#include "llfloaterimagepreview.h"
#include "llimfloater.h"
@@ -105,6 +106,7 @@
#include "llfloaterurldisplay.h"
#include "llfloatervoicedevicesettings.h"
#include "llfloaterwater.h"
+#include "llfloaterwhitelistentry.h"
#include "llfloaterwindlight.h"
#include "llfloaterworldmap.h"
#include "llinspectavatar.h"
@@ -164,8 +166,8 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>);
LLFloaterReg::add("group_picker", "floater_choose_group.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGroupPicker>);
+ LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);
LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
- LLFloaterReg::add("html_simple", "floater_html_simple.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHtmlSimple>);
LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>);
@@ -178,6 +180,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>);
LLFloaterReg::add("media_browser", "floater_media_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaBrowser>);
+ LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);
LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);
@@ -238,17 +241,13 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("voice_call", "floater_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCall>);
+ LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>);
LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>);
// *NOTE: Please keep these alphabetized for easier merges
// debug use only
LLFloaterReg::add("media_remote_ctrl", "floater_media_remote.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaRemoteCtrl>);
-
- // Untested / dangerous - not for release
-#if !LL_RELEASE_FOR_DOWNLOAD
- LLFloaterReg::add("buy_currency_html", "floater_html_simple.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHtmlCurrency>);
-#endif
LLFloaterReg::registerControlVariables(); // Make sure visibility and rect controls get preserved when saving
}
diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp
new file mode 100644
index 0000000000..0e0727e382
--- /dev/null
+++ b/indra/newview/llviewerhelp.cpp
@@ -0,0 +1,125 @@
+/**
+ * @file llviewerhelp.cpp
+ * @brief Utility functions for the Help system
+ * @author Tofu Linden
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterhelpbrowser.h"
+#include "llfloaterreg.h"
+#include "llfocusmgr.h"
+#include "llviewercontrol.h"
+#include "llversionviewer.h"
+#include "llappviewer.h"
+
+#include "llviewerhelputil.h"
+#include "llviewerhelp.h"
+
+
+//////////////////////////////
+// implement LLHelp interface
+
+void LLViewerHelp::showTopic(const std::string &topic)
+{
+ showHelp();
+
+ if( gSavedSettings.getBOOL("HelpUseLocal") )
+ {
+ LLFloaterHelpBrowser* helpbrowser = dynamic_cast<LLFloaterHelpBrowser*>(LLFloaterReg::getInstance("help_browser"));
+ helpbrowser->navigateToLocalPage( "help-offline" , "index.html" );
+ }
+ else
+ {
+ const LLOSInfo& osinfo = LLAppViewer::instance()->getOSInfo();
+ std::string helpURL = LLViewerHelpUtil::buildHelpURL( topic, gSavedSettings, osinfo );
+ setRawURL( helpURL );
+ }
+}
+
+std::string LLViewerHelp::defaultTopic()
+{
+ // *hack: to be done properly
+ return "this_is_fallbacktopic";
+}
+
+//////////////////////////////
+// our own interfaces
+
+std::string LLViewerHelp::getTopicFromFocus()
+{
+ // use UI element with viewer's keyboard focus as basis for searching
+ LLUICtrl* focused = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+
+ if (focused)
+ {
+ std::string topic;
+ if (focused->findHelpTopic(topic))
+ {
+ return topic;
+ }
+ }
+
+ // didn't find a help topic in the UI hierarchy for focused
+ // element, return the fallback topic name instead.
+ return defaultTopic();
+}
+
+// static
+void LLViewerHelp::showHelp()
+{
+ LLFloaterHelpBrowser* helpbrowser = dynamic_cast<LLFloaterHelpBrowser*>(LLFloaterReg::getInstance("help_browser"));
+ if (helpbrowser)
+ {
+ BOOL visible = TRUE;
+ BOOL take_focus = TRUE;
+ helpbrowser->setVisible(visible);
+ helpbrowser->setFrontmost(take_focus);
+ }
+ else
+ {
+ llwarns << "Eep, help_browser floater not found" << llendl;
+ }
+}
+
+// static
+void LLViewerHelp::setRawURL(std::string url)
+{
+ LLFloaterHelpBrowser* helpbrowser = dynamic_cast<LLFloaterHelpBrowser*>(LLFloaterReg::getInstance("help_browser"));
+ if (helpbrowser)
+ {
+ helpbrowser->openMedia(url);
+ }
+ else
+ {
+ llwarns << "Eep, help_browser floater not found" << llendl;
+ }
+}
+
diff --git a/indra/newview/llviewerhelp.h b/indra/newview/llviewerhelp.h
new file mode 100644
index 0000000000..17aab6f239
--- /dev/null
+++ b/indra/newview/llviewerhelp.h
@@ -0,0 +1,65 @@
+/**
+ * @file llviewerhelp.h
+ * @brief Utility functions for the Help system
+ * @author Tofu Linden
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVIEWERHELP_H
+#define LL_LLVIEWERHELP_H
+
+// The Help UI lives in llfloaterhelpbrowser, llviewerhelp provides a
+// layer of abstraction that protects help-system-using code from the details of
+// the Help UI floater and how help topics are converted into URLs.
+
+#include "llhelp.h" // our abstract base
+#include "llsingleton.h"
+
+class LLUICtrl;
+
+class LLViewerHelp : public LLHelp, public LLSingleton<LLViewerHelp>
+{
+ friend class LLSingleton<LLViewerHelp>;
+
+ public:
+ /// display the specified help topic in the help viewer
+ /*virtual*/ void showTopic(const std::string &topic);
+
+ /// return default (fallback) topic name suitable for showTopic()
+ /*virtual*/ std::string defaultTopic();
+
+ // return topic derived from viewer UI focus, else default topic
+ std::string getTopicFromFocus();
+
+ private:
+ static void showHelp(); // make sure help UI is visible & raised
+ static void setRawURL(std::string url); // send URL to help UI
+};
+
+#endif // header guard
diff --git a/indra/newview/llviewerhelputil.cpp b/indra/newview/llviewerhelputil.cpp
new file mode 100644
index 0000000000..c1555eacdc
--- /dev/null
+++ b/indra/newview/llviewerhelputil.cpp
@@ -0,0 +1,114 @@
+/**
+ * @file llviewerhelp.cpp
+ * @brief Utility functions for the Help system
+ * @author Soft Linden
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llversionviewer.h"
+
+//#include "llfloaterhelpbrowser.h"
+//#include "llfloaterreg.h"
+//#include "llfocusmgr.h"
+//#include "llviewercontrol.h"
+//#include "llappviewer.h"
+
+#include "llstring.h"
+#include "lluri.h"
+#include "llsys.h"
+
+#include "llcontrol.h"
+
+#include "llviewerhelputil.h"
+
+
+//////////////////////////////////////////////
+// Build a help URL from a topic and formatter
+
+//static
+std::string LLViewerHelpUtil::helpURLEncode( const std::string &component )
+{
+ // Every character rfc3986 allows as unreserved in 2.3, minus the tilde
+ // which we may grant special meaning. Yay.
+ const char* allowed =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"
+ "-._";
+ std::string escaped = LLURI::escape(component, allowed);
+
+ return escaped;
+}
+
+static std::string buildHelpVersion( const U32 ver_int )
+{
+ std::ostringstream ver_str;
+ ver_str << ver_int;
+ return ver_str.str(); // not encoded - numbers are rfc3986-safe
+}
+
+//static
+std::string LLViewerHelpUtil::buildHelpURL( const std::string &topic,
+ LLControlGroup &savedSettings,
+ const LLOSInfo &osinfo )
+{
+ std::string helpURL = savedSettings.getString("HelpURLFormat");
+ LLSD substitution;
+ substitution["TOPIC"] = helpURLEncode(topic);
+
+ substitution["CHANNEL"] = helpURLEncode(savedSettings.getString("VersionChannelName"));
+
+ // *TODO: We should put this version pattern in a central place; this and near
+ // equivalents are replicated in other code - what's a good location?
+ std::ostringstream version;
+ version << LL_VERSION_MAJOR << "."
+ << LL_VERSION_MINOR << "."
+ << LL_VERSION_PATCH << "."
+ << LL_VERSION_BUILD;
+ substitution["VERSION"] = helpURLEncode(version.str());
+ substitution["VERSION_MAJOR"] = buildHelpVersion(LL_VERSION_MAJOR);
+ substitution["VERSION_MINOR"] = buildHelpVersion(LL_VERSION_MINOR);
+ substitution["VERSION_PATCH"] = buildHelpVersion(LL_VERSION_PATCH);
+ substitution["VERSION_BUILD"] = buildHelpVersion(LL_VERSION_BUILD);
+
+ substitution["OS"] = helpURLEncode(osinfo.getOSStringSimple());
+
+ std::string language = savedSettings.getString("Language");
+ if( language.empty() || language == "default" )
+ {
+ language = savedSettings.getString("SystemLanguage");
+ }
+ substitution["LANGUAGE"] = helpURLEncode(language);
+
+ LLStringUtil::format(helpURL, substitution);
+
+ return helpURL;
+}
diff --git a/indra/newview/llviewerhelputil.h b/indra/newview/llviewerhelputil.h
new file mode 100644
index 0000000000..8ee0d96023
--- /dev/null
+++ b/indra/newview/llviewerhelputil.h
@@ -0,0 +1,49 @@
+/**
+ * @file llviewerhelputil.h
+ * @brief Utility functions for the Help system
+ * @author Soft Linden
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVIEWERHELPUTIL_H
+#define LL_LLVIEWERHELPUTIL_H
+
+class LLControlGroup;
+class LLOSInfo;
+
+class LLViewerHelpUtil
+{
+ public:
+ static std::string helpURLEncode( const std::string &component );
+ static std::string buildHelpURL( const std::string &topic,
+ LLControlGroup &savedSettings,
+ const LLOSInfo &osinfo);
+};
+
+#endif // header guard
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index f033d66c1f..100a34291b 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -35,12 +35,14 @@
#include "llviewermedia.h"
#include "llviewermediafocus.h"
#include "llmimetypes.h"
+#include "llmediaentry.h"
#include "llviewercontrol.h"
#include "llviewertexture.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
#include "llversionviewer.h"
#include "llviewertexturelist.h"
+#include "llvovolume.h"
#include "llpluginclassmedia.h"
#include "llevent.h" // LLSimpleListener
@@ -95,10 +97,10 @@ bool LLViewerMediaEventEmitter::remObserver( LLViewerMediaObserver* observer )
///////////////////////////////////////////////////////////////////////////////
//
-void LLViewerMediaEventEmitter::emitEvent( LLPluginClassMedia* media, LLPluginClassMediaOwner::EMediaEvent event )
+void LLViewerMediaEventEmitter::emitEvent( LLPluginClassMedia* media, LLViewerMediaObserver::EMediaEvent event )
{
+ // Broadcast the event to any observers.
observerListType::iterator iter = mObservers.begin();
-
while( iter != mObservers.end() )
{
LLViewerMediaObserver *self = *iter;
@@ -166,55 +168,127 @@ public:
};
typedef std::vector<LLViewerMediaImpl*> impl_list;
static impl_list sViewerMediaImplList;
+static LLTimer sMediaCreateTimer;
+static const F32 LLVIEWERMEDIA_CREATE_DELAY = 1.0f;
+
+//////////////////////////////////////////////////////////////////////////////////////////
+static void add_media_impl(LLViewerMediaImpl* media)
+{
+ sViewerMediaImplList.push_back(media);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+static void remove_media_impl(LLViewerMediaImpl* media)
+{
+ impl_list::iterator iter = sViewerMediaImplList.begin();
+ impl_list::iterator end = sViewerMediaImplList.end();
+
+ for(; iter != end; iter++)
+ {
+ if(media == *iter)
+ {
+ sViewerMediaImplList.erase(iter);
+ return;
+ }
+ }
+}
+
//////////////////////////////////////////////////////////////////////////////////////////
// LLViewerMedia
//////////////////////////////////////////////////////////////////////////////////////////
// static
-viewer_media_t LLViewerMedia::newMediaImpl(const std::string& media_url,
- const LLUUID& texture_id,
- S32 media_width, S32 media_height, U8 media_auto_scale,
- U8 media_loop,
- std::string mime_type)
+viewer_media_t LLViewerMedia::newMediaImpl(
+ const LLUUID& texture_id,
+ S32 media_width,
+ S32 media_height,
+ U8 media_auto_scale,
+ U8 media_loop)
{
LLViewerMediaImpl* media_impl = getMediaImplFromTextureID(texture_id);
if(media_impl == NULL || texture_id.isNull())
{
// Create the media impl
- media_impl = new LLViewerMediaImpl(media_url, texture_id, media_width, media_height, media_auto_scale, media_loop, mime_type);
- sViewerMediaImplList.push_back(media_impl);
+ media_impl = new LLViewerMediaImpl(texture_id, media_width, media_height, media_auto_scale, media_loop);
}
else
{
media_impl->stop();
media_impl->mTextureId = texture_id;
- media_impl->mMediaURL = media_url;
media_impl->mMediaWidth = media_width;
media_impl->mMediaHeight = media_height;
media_impl->mMediaAutoScale = media_auto_scale;
media_impl->mMediaLoop = media_loop;
- if(! media_url.empty())
- media_impl->navigateTo(media_url, mime_type, true);
}
+
return media_impl;
}
-//////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::removeMedia(LLViewerMediaImpl* media)
-{
- impl_list::iterator iter = sViewerMediaImplList.begin();
- impl_list::iterator end = sViewerMediaImplList.end();
+viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self)
+{
+ // Try to find media with the same media ID
+ viewer_media_t media_impl = getMediaImplFromTextureID(media_entry->getMediaID());
+
+ bool was_loaded = false;
+ bool needs_navigate = false;
- for(; iter != end; iter++)
+ if(media_impl)
+ {
+ was_loaded = media_impl->hasMedia();
+
+ media_impl->setHomeURL(media_entry->getHomeURL());
+
+ media_impl->mMediaAutoScale = media_entry->getAutoScale();
+ media_impl->mMediaLoop = media_entry->getAutoLoop();
+ media_impl->mMediaWidth = media_entry->getWidthPixels();
+ media_impl->mMediaHeight = media_entry->getHeightPixels();
+ if (media_impl->mMediaSource)
+ {
+ media_impl->mMediaSource->setAutoScale(media_impl->mMediaAutoScale);
+ media_impl->mMediaSource->setLoop(media_impl->mMediaLoop);
+ media_impl->mMediaSource->setSize(media_entry->getWidthPixels(), media_entry->getHeightPixels());
+ }
+
+ if((was_loaded || media_entry->getAutoPlay()) && !update_from_self)
+ {
+ if(!media_entry->getCurrentURL().empty())
+ {
+ needs_navigate = (media_entry->getCurrentURL() != previous_url);
+ }
+ else if(!media_entry->getHomeURL().empty())
+ {
+ needs_navigate = (media_entry->getHomeURL() != previous_url);
+ }
+ }
+ }
+ else
{
- if(media == *iter)
+ media_impl = newMediaImpl(
+ media_entry->getMediaID(),
+ media_entry->getWidthPixels(),
+ media_entry->getHeightPixels(),
+ media_entry->getAutoScale(),
+ media_entry->getAutoLoop());
+
+ media_impl->setHomeURL(media_entry->getHomeURL());
+
+ if(media_entry->getAutoPlay())
{
- sViewerMediaImplList.erase(iter);
- return;
+ needs_navigate = true;
}
}
+
+ if(media_impl && needs_navigate)
+ {
+ std::string url = media_entry->getCurrentURL();
+ if(url.empty())
+ url = media_entry->getHomeURL();
+
+ media_impl->navigateTo(url, "", true, true);
+ }
+
+ return media_impl;
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -323,6 +397,36 @@ void LLViewerMedia::setVolume(F32 volume)
}
}
+// This is the predicate function used to sort sViewerMediaImplList by priority.
+static inline bool compare_impl_interest(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2)
+{
+ if(i1->hasFocus())
+ {
+ // The item with user focus always comes to the front of the list, period.
+ return true;
+ }
+ else if(i2->hasFocus())
+ {
+ // The item with user focus always comes to the front of the list, period.
+ return false;
+ }
+ else if(i1->getUsedInUI() && !i2->getUsedInUI())
+ {
+ // i1 is a UI element, i2 is not. This makes i1 "less than" i2, so it sorts earlier in our list.
+ return true;
+ }
+ else if(i2->getUsedInUI() && !i1->getUsedInUI())
+ {
+ // i2 is a UI element, i1 is not. This makes i2 "less than" i1, so it sorts earlier in our list.
+ return false;
+ }
+ else
+ {
+ // The object with the larger interest value should be earlier in the list, so we reverse the sense of the comparison here.
+ return (i1->getInterest() > i2->getInterest());
+ }
+}
+
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::updateMedia()
@@ -334,32 +438,138 @@ void LLViewerMedia::updateMedia()
{
LLViewerMediaImpl* pimpl = *iter;
pimpl->update();
+ pimpl->calculateInterest();
}
+
+ // Sort the static instance list using our interest criteria
+ std::stable_sort(sViewerMediaImplList.begin(), sViewerMediaImplList.end(), compare_impl_interest);
+
+ // Go through the list again and adjust according to priority.
+ iter = sViewerMediaImplList.begin();
+ end = sViewerMediaImplList.end();
+
+ F64 total_cpu = 0.0f;
+ int impl_count_total = 0;
+ int impl_count_interest_low = 0;
+ int impl_count_interest_normal = 0;
+
+#if 0
+ LL_DEBUGS("PluginPriority") << "Sorted impls:" << llendl;
+#endif
+
+ U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal");
+ U32 max_normal = gSavedSettings.getU32("PluginInstancesNormal");
+ U32 max_low = gSavedSettings.getU32("PluginInstancesLow");
+ F32 max_cpu = gSavedSettings.getF32("PluginInstancesCPULimit");
+ // Setting max_cpu to 0.0 disables CPU usage checking.
+ bool check_cpu_usage = (max_cpu != 0.0f);
+
+ // Notes on tweakable params:
+ // max_instances must be set high enough to allow the various instances used in the UI (for the help browser, search, etc.) to be loaded.
+ // If max_normal + max_low is less than max_instances, things will tend to get unloaded instead of being set to slideshow.
+
+ for(; iter != end; iter++)
+ {
+ LLViewerMediaImpl* pimpl = *iter;
+
+ LLPluginClassMedia::EPriority new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
+
+ if(impl_count_total > (int)max_instances)
+ {
+ // Hard limit on the number of instances that will be loaded at one time
+ new_priority = LLPluginClassMedia::PRIORITY_UNLOADED;
+ }
+ else if(!pimpl->getVisible())
+ {
+ new_priority = LLPluginClassMedia::PRIORITY_HIDDEN;
+ }
+ else if(pimpl->hasFocus())
+ {
+ new_priority = LLPluginClassMedia::PRIORITY_HIGH;
+ }
+ else if(pimpl->getUsedInUI())
+ {
+ new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
+ }
+ else
+ {
+ // Look at interest and CPU usage for instances that aren't in any of the above states.
+
+ // Heuristic -- if the media texture's approximate screen area is less than 1/4 of the native area of the texture,
+ // turn it down to low instead of normal. This may downsample for plugins that support it.
+ bool media_is_small = pimpl->getInterest() < (pimpl->getApproximateTextureInterest() / 4);
+
+ if(pimpl->getInterest() == 0.0f)
+ {
+ // This media is completely invisible, due to being outside the view frustrum or out of range.
+ new_priority = LLPluginClassMedia::PRIORITY_HIDDEN;
+ }
+ else if(check_cpu_usage && (total_cpu > max_cpu))
+ {
+ // Higher priority plugins have already used up the CPU budget. Set remaining ones to slideshow priority.
+ new_priority = LLPluginClassMedia::PRIORITY_SLIDESHOW;
+ }
+ else if((impl_count_interest_normal < (int)max_normal) && !media_is_small)
+ {
+ // Up to max_normal inworld get normal priority
+ new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
+ impl_count_interest_normal++;
+ }
+ else if (impl_count_interest_low + impl_count_interest_normal < (int)max_low + (int)max_normal)
+ {
+ // The next max_low inworld get turned down
+ new_priority = LLPluginClassMedia::PRIORITY_LOW;
+ impl_count_interest_low++;
+
+ // Set the low priority size for downsampling to approximately the size the texture is displayed at.
+ {
+ F32 approximate_interest_dimension = fsqrtf(pimpl->getInterest());
+
+ pimpl->setLowPrioritySizeLimit(llround(approximate_interest_dimension));
+ }
+ }
+ else
+ {
+ // Any additional impls (up to max_instances) get very infrequent time
+ new_priority = LLPluginClassMedia::PRIORITY_SLIDESHOW;
+ }
+ }
+
+ pimpl->setPriority(new_priority);
+
+#if 0
+ LL_DEBUGS("PluginPriority") << " " << pimpl
+ << ", setting priority to " << new_priority
+ << (pimpl->hasFocus()?", HAS FOCUS":"")
+ << (pimpl->getUsedInUI()?", is UI":"")
+ << ", cpu " << pimpl->getCPUUsage()
+ << ", interest " << pimpl->getInterest()
+ << ", media url " << pimpl->getMediaURL() << llendl;
+#endif
+
+ total_cpu += pimpl->getCPUUsage();
+ impl_count_total++;
+ }
+
+ LL_DEBUGS("PluginPriority") << "Total reported CPU usage is " << total_cpu << llendl;
+
}
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::cleanupClass()
{
- // This is no longer necessary, since the list is no longer smart pointers.
-#if 0
- while(!sViewerMediaImplList.empty())
- {
- sViewerMediaImplList.pop_back();
- }
-#endif
+ // This is no longer necessary, since sViewerMediaImplList is no longer smart pointers.
}
//////////////////////////////////////////////////////////////////////////////////////////
// LLViewerMediaImpl
//////////////////////////////////////////////////////////////////////////////////////////
-LLViewerMediaImpl::LLViewerMediaImpl(const std::string& media_url,
- const LLUUID& texture_id,
+LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
S32 media_width,
S32 media_height,
U8 media_auto_scale,
- U8 media_loop,
- const std::string& mime_type)
+ U8 media_loop)
:
mMediaSource( NULL ),
mMovieImageHasMips(false),
@@ -368,13 +578,30 @@ LLViewerMediaImpl::LLViewerMediaImpl(const std::string& media_url,
mMediaHeight(media_height),
mMediaAutoScale(media_auto_scale),
mMediaLoop(media_loop),
- mMediaURL(media_url),
- mMimeType(mime_type),
mNeedsNewTexture(true),
mSuspendUpdates(false),
- mVisible(true)
+ mVisible(true),
+ mLastSetCursor( UI_CURSOR_ARROW ),
+ mMediaNavState( MEDIANAVSTATE_NONE ),
+ mInterest(0.0f),
+ mUsedInUI(false),
+ mHasFocus(false),
+ mPriority(LLPluginClassMedia::PRIORITY_UNLOADED),
+ mDoNavigateOnLoad(false),
+ mDoNavigateOnLoadServerRequest(false),
+ mIsUpdated(false)
{
- createMediaSource();
+
+ add_media_impl(this);
+
+ // connect this media_impl to the media texture, creating it if it doesn't exist.0
+ // This is necessary because we need to be able to use getMaxVirtualSize() even if the media plugin is not loaded.
+ LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture(mTextureId);
+ if(media_tex)
+ {
+ media_tex->setMediaImpl();
+ }
+
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -386,7 +613,26 @@ LLViewerMediaImpl::~LLViewerMediaImpl()
}
destroyMediaSource();
- LLViewerMedia::removeMedia(this);
+
+ LLViewerMediaTexture::removeMediaImplFromTexture(mTextureId) ;
+
+ remove_media_impl(this);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::emitEvent(LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event)
+{
+ // Broadcast to observers using the superclass version
+ LLViewerMediaEventEmitter::emitEvent(plugin, event);
+
+ // If this media is on one or more LLVOVolume objects, tell them about the event as well.
+ std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
+ while(iter != mObjectList.end())
+ {
+ LLVOVolume *self = *iter;
+ ++iter;
+ self->mediaEvent(this, plugin, event);
+ }
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -396,11 +642,7 @@ bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type)
{
if(! initializePlugin(mime_type))
{
- LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << mime_type << LL_ENDL;
- LLSD args;
- args["MIME_TYPE"] = mime_type;
- LLNotifications::instance().add("NoPlugin", args);
-
+ // This may be the case where the plugin's priority is PRIORITY_UNLOADED
return false;
}
}
@@ -412,29 +654,42 @@ bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type)
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::createMediaSource()
{
- if(! mMediaURL.empty())
+ if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
{
- navigateTo(mMediaURL, mMimeType, true);
+ // This media shouldn't be created yet.
+ return;
}
- else if(! mMimeType.empty())
+
+ if(mDoNavigateOnLoad)
{
- initializeMedia(mMimeType);
+ if(! mMediaURL.empty())
+ {
+ navigateTo(mMediaURL, mMimeType, false, mDoNavigateOnLoadServerRequest);
+ }
+ else if(! mMimeType.empty())
+ {
+ initializeMedia(mMimeType);
+ }
}
-
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::destroyMediaSource()
{
mNeedsNewTexture = true;
- if(! mMediaSource)
+
+ // Tell the viewer media texture it's no longer active
+ LLViewerMediaTexture* oldImage = LLViewerTextureManager::findMediaTexture( mTextureId );
+ if (oldImage)
{
- return;
+ oldImage->setPlaying(FALSE) ;
}
- // Restore the texture
- updateMovieImage(LLUUID::null, false);
- delete mMediaSource;
- mMediaSource = NULL;
+
+ if(mMediaSource)
+ {
+ delete mMediaSource;
+ mMediaSource = NULL;
+ }
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -487,6 +742,11 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
}
}
+ LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << media_type << LL_ENDL;
+ LLSD args;
+ args["MIME_TYPE"] = media_type;
+ LLNotifications::instance().add("NoPlugin", args);
+
return NULL;
}
@@ -506,7 +766,15 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
// and unconditionally set the mime type
mMimeType = media_type;
- LLPluginClassMedia* media_source = newSourceFromMediaType(media_type, this, mMediaWidth, mMediaHeight);
+ if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
+ {
+ // This impl should not be loaded at this time.
+ LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL;
+
+ return false;
+ }
+
+ LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight);
if (media_source)
{
@@ -543,13 +811,11 @@ void LLViewerMediaImpl::play()
{
if(!initializePlugin(mMimeType))
{
- // Plugin failed initialization... should assert or something
+ // This may be the case where the plugin's priority is PRIORITY_UNLOADED
return;
}
}
- // updateMovieImage(mTextureId, true);
-
mMediaSource->loadURI( mMediaURL );
if(/*mMediaSource->pluginSupportsMediaTime()*/ true)
{
@@ -606,6 +872,8 @@ void LLViewerMediaImpl::setVolume(F32 volume)
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::focus(bool focus)
{
+ mHasFocus = focus;
+
if (mMediaSource)
{
// call focus just for the hell of it, even though this apopears to be a nop
@@ -621,11 +889,19 @@ void LLViewerMediaImpl::focus(bool focus)
}
//////////////////////////////////////////////////////////////////////////////////////////
+bool LLViewerMediaImpl::hasFocus() const
+{
+ // FIXME: This might be able to be a bit smarter by hooking into LLViewerMediaFocus, etc.
+ return mHasFocus;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::mouseDown(S32 x, S32 y)
{
scaleMouse(&x, &y);
mLastMouseX = x;
mLastMouseY = y;
+// llinfos << "mouse down (" << x << ", " << y << ")" << llendl;
if (mMediaSource)
{
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, x, y, 0);
@@ -638,6 +914,7 @@ void LLViewerMediaImpl::mouseUp(S32 x, S32 y)
scaleMouse(&x, &y);
mLastMouseX = x;
mLastMouseY = y;
+// llinfos << "mouse up (" << x << ", " << y << ")" << llendl;
if (mMediaSource)
{
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, x, y, 0);
@@ -647,9 +924,10 @@ void LLViewerMediaImpl::mouseUp(S32 x, S32 y)
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::mouseMove(S32 x, S32 y)
{
- scaleMouse(&x, &y);
+ scaleMouse(&x, &y);
mLastMouseX = x;
mLastMouseY = y;
+// llinfos << "mouse move (" << x << ", " << y << ")" << llendl;
if (mMediaSource)
{
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_MOVE, x, y, 0);
@@ -657,6 +935,37 @@ void LLViewerMediaImpl::mouseMove(S32 x, S32 y)
}
//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::mouseDown(const LLVector2& texture_coords)
+{
+ if(mMediaSource)
+ {
+ mouseDown(
+ llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth()),
+ llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight()));
+ }
+}
+
+void LLViewerMediaImpl::mouseUp(const LLVector2& texture_coords)
+{
+ if(mMediaSource)
+ {
+ mouseUp(
+ llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth()),
+ llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight()));
+ }
+}
+
+void LLViewerMediaImpl::mouseMove(const LLVector2& texture_coords)
+{
+ if(mMediaSource)
+ {
+ mouseMove(
+ llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth()),
+ llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight()));
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::mouseLeftDoubleClick(S32 x, S32 y)
{
scaleMouse(&x, &y);
@@ -694,6 +1003,10 @@ BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask)
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::navigateHome()
{
+ mMediaURL = mHomeURL;
+ mDoNavigateOnLoad = !mMediaURL.empty();
+ mDoNavigateOnLoadServerRequest = false;
+
if(mMediaSource)
{
mMediaSource->loadURI( mHomeURL );
@@ -701,17 +1014,43 @@ void LLViewerMediaImpl::navigateHome()
}
//////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type, bool rediscover_type)
+void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type, bool rediscover_type, bool server_request)
{
+ if(server_request)
+ {
+ setNavState(MEDIANAVSTATE_SERVER_SENT);
+ }
+ else
+ {
+ setNavState(MEDIANAVSTATE_NONE);
+ }
+
+ // Always set the current URL.
+ mMediaURL = url;
+
+ // If the current URL is not null, make the instance do a navigate on load.
+ mDoNavigateOnLoad = !mMediaURL.empty();
+
+ // and if this was a server request, the navigate on load will also need to be one.
+ mDoNavigateOnLoadServerRequest = server_request;
+
+ if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
+ {
+ // This impl should not be loaded at this time.
+ LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL;
+
+ return;
+ }
+
if(rediscover_type)
{
- LLURI uri(url);
+ LLURI uri(mMediaURL);
std::string scheme = uri.scheme();
if(scheme.empty() || "http" == scheme || "https" == scheme)
{
- LLHTTPClient::getHeaderOnly( url, new LLMimeDiscoveryResponder(this));
+ LLHTTPClient::getHeaderOnly( mMediaURL, new LLMimeDiscoveryResponder(this));
}
else if("data" == scheme || "file" == scheme || "about" == scheme)
{
@@ -719,7 +1058,7 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
// We use "data" internally for a text/html url for loading the login screen
if(initializeMedia("text/html"))
{
- mMediaSource->loadURI( url );
+ mMediaSource->loadURI( mMediaURL );
}
}
else
@@ -727,24 +1066,23 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
// This catches 'rtsp://' urls
if(initializeMedia(scheme))
{
- mMediaSource->loadURI( url );
+ mMediaSource->loadURI( mMediaURL );
}
}
}
else if (mMediaSource)
{
- mMediaSource->loadURI( url );
+ mMediaSource->loadURI( mMediaURL );
}
else if(initializeMedia(mime_type) && mMediaSource)
{
- mMediaSource->loadURI( url );
+ mMediaSource->loadURI( mMediaURL );
}
else
{
LL_WARNS("Media") << "Couldn't navigate to: " << url << " as there is no media type for: " << mime_type << LL_ENDL;
return;
}
- mMediaURL = url;
}
@@ -806,49 +1144,27 @@ bool LLViewerMediaImpl::canNavigateBack()
return result;
}
-
//////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active)
+void LLViewerMediaImpl::update()
{
- // IF the media image hasn't changed, do nothing
- if (mTextureId == uuid)
- {
- return;
- }
- // If we have changed media uuid, restore the old one
- if (!mTextureId.isNull())
+ if(mMediaSource == NULL)
{
- LLViewerMediaTexture* old_image = LLViewerTextureManager::findMediaTexture( mTextureId );
- if (old_image)
+ if(mPriority != LLPluginClassMedia::PRIORITY_UNLOADED)
{
- old_image->setPlaying(FALSE);
- LLViewerTexture* original_texture = old_image->getOldTexture();
- if(original_texture)
+ // This media may need to be loaded.
+ if(sMediaCreateTimer.hasExpired())
{
- old_image->switchToTexture(original_texture);
+ LL_DEBUGS("PluginPriority") << this << ": creating media based on timer expiration" << LL_ENDL;
+ createMediaSource();
+ sMediaCreateTimer.setTimerExpirySec(LLVIEWERMEDIA_CREATE_DELAY);
+ }
+ else
+ {
+ LL_DEBUGS("PluginPriority") << this << ": NOT creating media (waiting on timer)" << LL_ENDL;
}
}
}
- // If the movie is playing, set the new media image
- if (active && !uuid.isNull())
- {
- LLViewerMediaTexture* viewerImage = LLViewerTextureManager::findMediaTexture( uuid );
- if( viewerImage )
- {
- mTextureId = uuid;
-
- // Can't use mipmaps for movies because they don't update the full image
- mMovieImageHasMips = viewerImage->getUseMipMaps();
- viewerImage->reinit(FALSE);
- // FIXME
-// viewerImage->mIsMediaTexture = TRUE;
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::update()
-{
+
if(mMediaSource == NULL)
{
return;
@@ -877,6 +1193,10 @@ void LLViewerMediaImpl::update()
if(placeholder_image)
{
LLRect dirty_rect;
+
+ // Since we're updating this texture, we know it's playing. Tell the texture to do its replacement magic so it gets rendered.
+ placeholder_image->setPlaying(TRUE);
+
if(mMediaSource->getDirty(&dirty_rect))
{
// Constrain the dirty rect to be inside the texture
@@ -930,12 +1250,11 @@ LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
if (mNeedsNewTexture
|| placeholder_image->getUseMipMaps()
-// || ! placeholder_image->getType() == LLViewerTexture::MEDIA_TEXTURE
|| placeholder_image->getWidth() != mMediaSource->getTextureWidth()
|| placeholder_image->getHeight() != mMediaSource->getTextureHeight())
{
- llinfos << "initializing media placeholder" << llendl;
- llinfos << "movie image id " << mTextureId << llendl;
+ LL_DEBUGS("Media") << "initializing media placeholder" << LL_ENDL;
+ LL_DEBUGS("Media") << "movie image id " << mTextureId << LL_ENDL;
int texture_width = mMediaSource->getTextureWidth();
int texture_height = mMediaSource->getTextureHeight();
@@ -960,9 +1279,6 @@ LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
placeholder_image->createGLTexture(discard_level, raw);
- // placeholder_image->setExplicitFormat()
- placeholder_image->setUseMipMaps(FALSE);
-
// MEDIAOPT: set this dynamically on play/stop
// FIXME
// placeholder_image->mIsMediaTexture = true;
@@ -996,11 +1312,6 @@ void LLViewerMediaImpl::setVisible(bool visible)
createMediaSource();
}
}
-
- if(mMediaSource)
- {
- mMediaSource->setPriority(mVisible?LLPluginClassMedia::PRIORITY_NORMAL:LLPluginClassMedia::PRIORITY_HIDDEN);
- }
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -1059,7 +1370,7 @@ bool LLViewerMediaImpl::hasMedia()
}
//////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event)
+void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent event)
{
switch(event)
{
@@ -1070,11 +1381,77 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* self, LLPluginClass
LLNotifications::instance().add("MediaPluginFailed", args);
}
break;
+
+ case MEDIA_EVENT_CURSOR_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << plugin->getCursorName() << LL_ENDL;
+
+ std::string cursor = plugin->getCursorName();
+
+ if(cursor == "arrow")
+ mLastSetCursor = UI_CURSOR_ARROW;
+ else if(cursor == "ibeam")
+ mLastSetCursor = UI_CURSOR_IBEAM;
+ else if(cursor == "splith")
+ mLastSetCursor = UI_CURSOR_SIZEWE;
+ else if(cursor == "splitv")
+ mLastSetCursor = UI_CURSOR_SIZENS;
+ else if(cursor == "hand")
+ mLastSetCursor = UI_CURSOR_HAND;
+ else // for anything else, default to the arrow
+ mLastSetCursor = UI_CURSOR_ARROW;
+ }
+ break;
+
+ case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_BEGIN:
+ {
+ LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_BEGIN, uri is: " << plugin->getNavigateURI() << LL_ENDL;
+
+ if(getNavState() == MEDIANAVSTATE_SERVER_SENT)
+ {
+ setNavState(MEDIANAVSTATE_SERVER_BEGUN);
+ }
+ else
+ {
+ setNavState(MEDIANAVSTATE_BEGUN);
+ }
+ }
+ break;
+
+ case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE:
+ {
+ LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_COMPLETE, uri is: " << plugin->getNavigateURI() << LL_ENDL;
+ setNavState(MEDIANAVSTATE_NONE);
+ }
+ break;
+
+ case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED:
+ {
+ LL_DEBUGS("Media") << "MEDIA_EVENT_LOCATION_CHANGED, uri is: " << plugin->getLocation() << LL_ENDL;
+
+ if(getNavState() == MEDIANAVSTATE_BEGUN)
+ {
+ setNavState(MEDIANAVSTATE_FIRST_LOCATION_CHANGED);
+ }
+ else if(getNavState() == MEDIANAVSTATE_SERVER_BEGUN)
+ {
+ setNavState(MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED);
+ }
+ else
+ {
+ // Don't track redirects.
+ setNavState(MEDIANAVSTATE_NONE);
+ }
+ }
+ break;
+
+
default:
break;
}
+
// Just chain the event to observers.
- emitEvent(self, event);
+ emitEvent(plugin, event);
}
////////////////////////////////////////////////////////////////////////////////
@@ -1137,6 +1514,146 @@ LLViewerMediaImpl::canPaste() const
return FALSE;
}
+void LLViewerMediaImpl::setUpdated(BOOL updated)
+{
+ mIsUpdated = updated ;
+}
+
+BOOL LLViewerMediaImpl::isUpdated()
+{
+ return mIsUpdated ;
+}
+
+void LLViewerMediaImpl::calculateInterest()
+{
+ LLViewerMediaTexture* texture = LLViewerTextureManager::findMediaTexture( mTextureId );
+
+ if(texture != NULL)
+ {
+ mInterest = texture->getMaxVirtualSize();
+ }
+ else
+ {
+ // I don't think this case should ever be hit.
+ LL_WARNS("Plugin") << "no texture!" << LL_ENDL;
+ mInterest = 0.0f;
+ }
+}
+
+F64 LLViewerMediaImpl::getApproximateTextureInterest()
+{
+ F64 result = 0.0f;
+
+ if(mMediaSource)
+ {
+ result = mMediaSource->getFullWidth();
+ result *= mMediaSource->getFullHeight();
+ }
+
+ return result;
+}
+
+void LLViewerMediaImpl::setUsedInUI(bool used_in_ui)
+{
+ mUsedInUI = used_in_ui;
+
+ // HACK: Force elements used in UI to load right away.
+ // This fixes some issues where UI code that uses the browser instance doesn't expect it to be unloaded.
+ if(mUsedInUI && (mPriority == LLPluginClassMedia::PRIORITY_UNLOADED))
+ {
+ if(getVisible())
+ {
+ mPriority = LLPluginClassMedia::PRIORITY_NORMAL;
+ }
+ else
+ {
+ mPriority = LLPluginClassMedia::PRIORITY_HIDDEN;
+ }
+
+ createMediaSource();
+ }
+};
+
+F64 LLViewerMediaImpl::getCPUUsage() const
+{
+ F64 result = 0.0f;
+
+ if(mMediaSource)
+ {
+ result = mMediaSource->getCPUUsage();
+ }
+
+ return result;
+}
+
+void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority)
+{
+ mPriority = priority;
+
+ if(priority == LLPluginClassMedia::PRIORITY_UNLOADED)
+ {
+ if(mMediaSource)
+ {
+ // Need to unload the media source
+ destroyMediaSource();
+ }
+ }
+
+ if(mMediaSource)
+ {
+ mMediaSource->setPriority(mPriority);
+ }
+
+ // NOTE: loading (or reloading) media sources whose priority has risen above PRIORITY_UNLOADED is done in update().
+}
+
+void LLViewerMediaImpl::setLowPrioritySizeLimit(int size)
+{
+ if(mMediaSource)
+ {
+ mMediaSource->setLowPrioritySizeLimit(size);
+ }
+}
+
+void LLViewerMediaImpl::setNavState(EMediaNavState state)
+{
+ mMediaNavState = state;
+
+ switch (state)
+ {
+ case MEDIANAVSTATE_NONE: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_NONE" << llendl; break;
+ case MEDIANAVSTATE_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_BEGUN" << llendl; break;
+ case MEDIANAVSTATE_FIRST_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_FIRST_LOCATION_CHANGED" << llendl; break;
+ case MEDIANAVSTATE_SERVER_SENT: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_SENT" << llendl; break;
+ case MEDIANAVSTATE_SERVER_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_BEGUN" << llendl; break;
+ case MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED" << llendl; break;
+ }
+}
+
+
+void LLViewerMediaImpl::addObject(LLVOVolume* obj)
+{
+ std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
+ for(; iter != mObjectList.end() ; ++iter)
+ {
+ if(*iter == obj)
+ {
+ return ; //already in the list.
+ }
+ }
+
+ mObjectList.push_back(obj) ;
+}
+
+void LLViewerMediaImpl::removeObject(LLVOVolume* obj)
+{
+ mObjectList.remove(obj) ;
+}
+
+const std::list< LLVOVolume* >* LLViewerMediaImpl::getObjectList() const
+{
+ return &mObjectList ;
+}
//////////////////////////////////////////////////////////////////////////////////////////
//static
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 9a61394383..775f72d56f 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -41,9 +41,13 @@
#include "llviewermediaobserver.h"
+#include "llpluginclassmedia.h"
+
class LLViewerMediaImpl;
class LLUUID;
class LLViewerMediaTexture;
+class LLMediaEntry;
+class LLVOVolume ;
typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
///////////////////////////////////////////////////////////////////////////////
@@ -55,7 +59,7 @@ public:
bool addObserver( LLViewerMediaObserver* subject );
bool remObserver( LLViewerMediaObserver* subject );
- void emitEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event);
+ virtual void emitEvent(LLPluginClassMedia* self, LLViewerMediaObserver::EMediaEvent event);
private:
typedef std::list< LLViewerMediaObserver* > observerListType;
@@ -69,15 +73,13 @@ class LLViewerMedia
// Special case early init for just web browser component
// so we can show login screen. See .cpp file for details. JC
- static viewer_media_t newMediaImpl(const std::string& media_url,
- const LLUUID& texture_id,
- S32 media_width,
- S32 media_height,
- U8 media_auto_scale,
- U8 media_loop,
- std::string mime_type = "none/none");
+ static viewer_media_t newMediaImpl(const LLUUID& texture_id,
+ S32 media_width = 0,
+ S32 media_height = 0,
+ U8 media_auto_scale = false,
+ U8 media_loop = false);
- static void removeMedia(LLViewerMediaImpl* media);
+ static viewer_media_t updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self);
static LLViewerMediaImpl* getMediaImplFromTextureID(const LLUUID& texture_id);
static std::string getCurrentUserAgent();
static void updateBrowserUserAgent();
@@ -102,15 +104,18 @@ class LLViewerMediaImpl
LOG_CLASS(LLViewerMediaImpl);
public:
- LLViewerMediaImpl(const std::string& media_url,
+ LLViewerMediaImpl(
const LLUUID& texture_id,
S32 media_width,
S32 media_height,
U8 media_auto_scale,
- U8 media_loop,
- const std::string& mime_type);
+ U8 media_loop);
~LLViewerMediaImpl();
+
+ // Override inherited version from LLViewerMediaEventEmitter
+ virtual void emitEvent(LLPluginClassMedia* self, LLViewerMediaObserver::EMediaEvent event);
+
void createMediaSource();
void destroyMediaSource();
void setMediaType(const std::string& media_type);
@@ -126,36 +131,44 @@ public:
void seek(F32 time);
void setVolume(F32 volume);
void focus(bool focus);
+ // True if the impl has user focus.
+ bool hasFocus() const;
void mouseDown(S32 x, S32 y);
void mouseUp(S32 x, S32 y);
void mouseMove(S32 x, S32 y);
+ void mouseDown(const LLVector2& texture_coords);
+ void mouseUp(const LLVector2& texture_coords);
+ void mouseMove(const LLVector2& texture_coords);
void mouseLeftDoubleClick(S32 x,S32 y );
void mouseCapture();
void navigateHome();
- void navigateTo(const std::string& url, const std::string& mime_type = "", bool rediscover_type = false);
+ void navigateTo(const std::string& url, const std::string& mime_type = "", bool rediscover_type = false, bool server_request = false);
void navigateStop();
bool handleKeyHere(KEY key, MASK mask);
bool handleUnicodeCharHere(llwchar uni_char);
bool canNavigateForward();
bool canNavigateBack();
std::string getMediaURL() { return mMediaURL; }
- std::string getMediaHomeURL() { return mHomeURL; }
+ std::string getHomeURL() { return mHomeURL; }
+ void setHomeURL(const std::string& home_url) { mHomeURL = home_url; };
std::string getMimeType() { return mMimeType; }
void scaleMouse(S32 *mouse_x, S32 *mouse_y);
void update();
- void updateMovieImage(const LLUUID& image_id, BOOL active);
void updateImagesMediaStreams();
LLUUID getMediaTextureID();
void suspendUpdates(bool suspend) { mSuspendUpdates = suspend; };
void setVisible(bool visible);
+ bool getVisible() const { return mVisible; };
bool isMediaPlaying();
bool isMediaPaused();
bool hasMedia();
+ ECursorType getLastSetCursor() { return mLastSetCursor; };
+
// utility function to create a ready-to-use media instance from a desired media type.
static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height);
@@ -191,7 +204,7 @@ public:
/*virtual*/ BOOL hasMouseCapture() { return gFocusMgr.getMouseCapture() == this; };
// Inherited from LLPluginClassMediaOwner
- /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent);
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent);
// LLEditMenuHandler overrides
/*virtual*/ void cut();
@@ -203,6 +216,45 @@ public:
/*virtual*/ void paste();
/*virtual*/ BOOL canPaste() const;
+ void addObject(LLVOVolume* obj) ;
+ void removeObject(LLVOVolume* obj) ;
+ const std::list< LLVOVolume* >* getObjectList() const ;
+ void setUpdated(BOOL updated) ;
+ BOOL isUpdated() ;
+
+ // Updates the "interest" value in this object
+ void calculateInterest();
+ F64 getInterest() const { return mInterest; };
+ F64 getApproximateTextureInterest();
+
+ // Mark this object as being used in a UI panel instead of on a prim
+ // This will be used as part of the interest sorting algorithm.
+ void setUsedInUI(bool used_in_ui);
+ bool getUsedInUI() const { return mUsedInUI; };
+
+ F64 getCPUUsage() const;
+
+ void setPriority(LLPluginClassMedia::EPriority priority);
+ LLPluginClassMedia::EPriority getPriority() { return mPriority; };
+
+ void setLowPrioritySizeLimit(int size);
+
+ typedef enum
+ {
+ MEDIANAVSTATE_NONE, // State is outside what we need to track for navigation.
+ MEDIANAVSTATE_BEGUN, // a MEDIA_EVENT_NAVIGATE_BEGIN has been received which was not server-directed
+ MEDIANAVSTATE_FIRST_LOCATION_CHANGED, // first LOCATION_CHANGED event after a non-server-directed BEGIN
+ MEDIANAVSTATE_SERVER_SENT, // server-directed nav has been requested, but MEDIA_EVENT_NAVIGATE_BEGIN hasn't been received yet
+ MEDIANAVSTATE_SERVER_BEGUN, // MEDIA_EVENT_NAVIGATE_BEGIN has been received which was server-directed
+ MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED // first LOCATION_CHANGED event after a server-directed BEGIN
+
+ }EMediaNavState;
+
+ // Returns the current nav state of the media.
+ // note that this will be updated BEFORE listeners and objects receive media messages
+ EMediaNavState getNavState() { return mMediaNavState; }
+ void setNavState(EMediaNavState state);
+
public:
// a single media url with some data and an impl.
LLPluginClassMedia* mMediaSource;
@@ -220,7 +272,19 @@ public:
bool mNeedsNewTexture;
bool mSuspendUpdates;
bool mVisible;
+ ECursorType mLastSetCursor;
+ EMediaNavState mMediaNavState;
+ F64 mInterest;
+ bool mUsedInUI;
+ bool mHasFocus;
+ LLPluginClassMedia::EPriority mPriority;
+ bool mDoNavigateOnLoad;
+ bool mDoNavigateOnLoadServerRequest;
+
+private:
+ BOOL mIsUpdated ;
+ std::list< LLVOVolume* > mObjectList ;
private:
LLViewerMediaTexture *updatePlaceholderImage();
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index e7576d5c76..f9377ab37b 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -47,6 +47,7 @@
#include "llparcel.h"
#include "llviewerparcelmgr.h"
#include "llweb.h"
+#include "llmediaentry.h"
//
// LLViewerMediaFocus
//
@@ -91,14 +92,38 @@ void LLViewerMediaFocus::cleanupClass()
void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl )
{
LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
+ if(mMediaImpl.notNull())
+ {
+ mMediaImpl->focus(false);
+ }
+
if (b && media_impl.notNull())
{
+ bool face_auto_zoom = false;
mMediaImpl = media_impl;
+ mMediaImpl->focus(true);
+
LLSelectMgr::getInstance()->deselectAll();
LLSelectMgr::getInstance()->selectObjectOnly(objectp, face);
+ if(objectp.notNull())
+ {
+ LLTextureEntry* tep = objectp->getTE(face);
+ if(! tep->hasMedia())
+ {
+ // Error condition
+ }
+ LLMediaEntry* mep = tep->getMediaData();
+ face_auto_zoom = mep->getAutoZoom();
+ if(! mep->getAutoPlay())
+ {
+ std::string url = mep->getCurrentURL().empty() ? mep->getHomeURL() : mep->getCurrentURL();
+ media_impl->navigateTo(url, "", true);
+ }
+ }
mFocus = LLSelectMgr::getInstance()->getSelection();
- if(mMediaHUD.get() && ! parcel->getMediaPreventCameraZoom())
+ if(mMediaHUD.get() && face_auto_zoom && ! parcel->getMediaPreventCameraZoom())
{
mMediaHUD.get()->resetZoomLevel();
mMediaHUD.get()->nextZoomLevel();
@@ -108,6 +133,7 @@ void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp
gFocusMgr.setKeyboardFocus(this);
}
mObjectID = objectp->getID();
+ mObjectFace = face;
// LLViewerMedia::addObserver(this, mObjectID);
@@ -133,6 +159,8 @@ void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp
// and null out the media impl
mMediaImpl = NULL;
+ mObjectID = LLUUID::null;
+ mObjectFace = 0;
}
if(mMediaHUD.get())
{
@@ -230,6 +258,12 @@ void LLViewerMediaFocus::setMouseOverFlag(bool b, viewer_media_t media_impl)
gHUDView->addChild(media_hud);
}
mMediaHUD.get()->setMediaImpl(media_impl);
+
+ if(mMediaImpl.notNull() && (mMediaImpl != media_impl))
+ {
+ mMediaImpl->focus(false);
+ }
+
mMediaImpl = media_impl;
}
mMouseOverFlag = b;
@@ -356,3 +390,8 @@ F32 LLViewerMediaFocus::getBBoxAspectRatio(const LLBBox& bbox, const LLVector3&
// Return the aspect ratio.
return *width / *height;
}
+
+bool LLViewerMediaFocus::isFocusedOnFace(LLPointer<LLViewerObject> objectp, S32 face)
+{
+ return objectp->getID() == mObjectID && face == mObjectFace;
+}
diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h
index a078d24b6a..2688a8b708 100644
--- a/indra/newview/llviewermediafocus.h
+++ b/indra/newview/llviewermediafocus.h
@@ -72,6 +72,9 @@ public:
void setPickInfo(LLPickInfo pick_info) { mPickInfo = pick_info; }
F32 getBBoxAspectRatio(const LLBBox& bbox, const LLVector3& normal, F32* height, F32* width, F32* depth);
+ // TODO: figure out why selection mgr hates me
+ bool isFocusedOnFace(LLPointer<LLViewerObject> objectp, S32 face);
+
protected:
/*virtual*/ void onFocusReceived();
/*virtual*/ void onFocusLost();
@@ -83,6 +86,7 @@ private:
LLPickInfo mPickInfo;
LLHandle<LLPanelMediaHUD> mMediaHUD;
LLUUID mObjectID;
+ S32 mObjectFace;
viewer_media_t mMediaImpl;
};
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index a0bd5f301b..12253455a3 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -103,9 +103,6 @@
#include "llfloatergodtools.h"
#include "llfloatergroupinvite.h"
#include "llfloatergroups.h"
-#include "llfloaterhtmlcurrency.h"
-#include "llfloatermediabrowser.h" // gViewerHtmlHelp
-#include "llfloaterhtmlsimple.h"
#include "llfloaterhud.h"
#include "llfloaterinspect.h"
#include "llfloaterlagmeter.h"
@@ -182,6 +179,7 @@
#include "lluuid.h"
#include "llviewercamera.h"
#include "llviewergenericmessage.h"
+#include "llviewerhelp.h"
#include "llviewertexturelist.h" // gTextureList
#include "llviewerinventory.h"
#include "llviewermenufile.h" // init_menu_file()
@@ -375,7 +373,6 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt
void dump_select_mgr(void*);
void dump_inventory(void*);
-void edit_ui(void*);
void toggle_visibility(void*);
BOOL get_visibility(void*);
@@ -1247,21 +1244,6 @@ class LLAdvancedBuyCurrencyTest : public view_listener_t
};
-////////////////////////
-// TOGGLE EDITABLE UI //
-////////////////////////
-
-
-class LLAdvancedToggleEditableUI : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- edit_ui(NULL);
- return true;
- }
-};
-
-
/////////////////////
// DUMP SELECT MGR //
/////////////////////
@@ -5587,11 +5569,6 @@ class LLObjectEnableSitOrStand : public view_listener_t
}
};
-void edit_ui(void*)
-{
- LLFloater::setEditModeEnabled(!LLFloater::getEditModeEnabled());
-}
-
void dump_select_mgr(void*)
{
LLSelectMgr::getInstance()->dump();
@@ -5649,8 +5626,8 @@ class LLShowFloater : public view_listener_t
}
else if (floater_name == "help f1")
{
- llinfos << "Spawning HTML help window" << llendl;
- gViewerHtmlHelp.show();
+ LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+ vhelp->showTopic(vhelp->getTopicFromFocus());
}
else if (floater_name == "complaint reporter")
{
@@ -7689,6 +7666,19 @@ class LLHelpShowFirstTimeTip : public view_listener_t
}
};
+void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y)
+{
+ static LLMenuGL* show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml",
+ gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if(gMenuHolder->hasVisibleMenu())
+ {
+ gMenuHolder->hideMenus();
+ }
+ show_navbar_context_menu->buildDrawLabels();
+ show_navbar_context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y);
+}
+
void initialize_menus()
{
// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
@@ -7886,7 +7876,6 @@ void initialize_menus()
// Advanced > UI
view_listener_t::addMenu(new LLAdvancedWebBrowserTest(), "Advanced.WebBrowserTest");
view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
- view_listener_t::addMenu(new LLAdvancedToggleEditableUI(), "Advanced.ToggleEditableUI");
view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
view_listener_t::addMenu(new LLAdvancedDumpFocusHolder(), "Advanced.DumpFocusHolder");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index cf482266d6..dd6aac2dd3 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -52,6 +52,7 @@ void show_debug_menus(); // checks for if menus should be shown first.
void toggle_debug_menus(void*);
void show_context_menu( S32 x, S32 y, MASK mask );
void show_build_mode_context_menu(S32 x, S32 y, MASK mask);
+void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y);
BOOL enable_save_into_inventory(void*);
void handle_reset_view();
void handle_cut(void*);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index d3d5f060e1..05011a1568 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -47,6 +47,7 @@
#include "llframetimer.h"
#include "llinventory.h"
#include "llmaterialtable.h"
+#include "llmediadataresponder.h"
#include "llmutelist.h"
#include "llnamevalue.h"
#include "llprimitive.h"
@@ -100,6 +101,8 @@
#include "llvowlsky.h"
#include "llmanip.h"
#include "lltrans.h"
+#include "llsdutil.h"
+#include "llmediaentry.h"
//#define DEBUG_UPDATE_TYPE
@@ -470,6 +473,7 @@ void LLViewerObject::cleanupVOClasses()
LLVOWater::cleanupClass();
LLVOTree::cleanupClass();
LLVOAvatar::cleanupClass();
+ LLVOVolume::cleanupClass();
}
// Replaces all name value pairs with data from \n delimited list
@@ -700,6 +704,42 @@ void LLViewerObject::hideExtraDisplayItems( BOOL hidden )
}
}
+U32 LLViewerObject::checkMediaURL(const std::string &media_url)
+{
+ U32 retval = (U32)0x0;
+ if (!mMedia && !media_url.empty())
+ {
+ retval |= MEDIA_URL_ADDED;
+ mMedia = new LLViewerObjectMedia;
+ mMedia->mMediaURL = media_url;
+ mMedia->mMediaType = LLViewerObject::MEDIA_SET;
+ mMedia->mPassedWhitelist = FALSE;
+ }
+ else if (mMedia)
+ {
+ if (media_url.empty())
+ {
+ retval |= MEDIA_URL_REMOVED;
+ delete mMedia;
+ mMedia = NULL;
+ }
+ else if (mMedia->mMediaURL != media_url) // <-- This is an optimization. If they are equal don't bother with below's test.
+ {
+ /*if (! (LLTextureEntry::getAgentIDFromMediaVersionString(media_url) == gAgent.getID() &&
+ LLTextureEntry::getVersionFromMediaVersionString(media_url) ==
+ LLTextureEntry::getVersionFromMediaVersionString(mMedia->mMediaURL) + 1))
+ */
+ {
+ // If the media URL is different and WE were not the one who
+ // changed it, mark dirty.
+ retval |= MEDIA_URL_UPDATED;
+ }
+ mMedia->mMediaURL = media_url;
+ mMedia->mPassedWhitelist = FALSE;
+ }
+ }
+ return retval;
+}
U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
@@ -1045,35 +1085,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
std::string media_url;
mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, media_url, block_num);
- //if (!media_url.empty())
- //{
- // llinfos << "WEBONPRIM media_url " << media_url << llendl;
- //}
- if (!mMedia && !media_url.empty())
- {
- retval |= MEDIA_URL_ADDED;
- mMedia = new LLViewerObjectMedia;
- mMedia->mMediaURL = media_url;
- mMedia->mMediaType = LLViewerObject::MEDIA_TYPE_WEB_PAGE;
- mMedia->mPassedWhitelist = FALSE;
- }
- else if (mMedia)
- {
- if (media_url.empty())
- {
- retval |= MEDIA_URL_REMOVED;
- delete mMedia;
- mMedia = NULL;
- }
- else if (mMedia->mMediaURL != media_url)
- {
- // We just added or changed a web page.
- retval |= MEDIA_URL_UPDATED;
- mMedia->mMediaURL = media_url;
- mMedia->mPassedWhitelist = FALSE;
- }
- }
-
+ retval |= checkMediaURL(media_url);
+
//
// Unpack particle system data
//
@@ -1456,31 +1469,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
mText = NULL;
}
+ std::string media_url;
if (value & 0x200)
{
- std::string media_url;
dp->unpackString(media_url, "MediaURL");
- if (!mMedia)
- {
- retval |= MEDIA_URL_ADDED;
- mMedia = new LLViewerObjectMedia;
- mMedia->mMediaURL = media_url;
- mMedia->mMediaType = LLViewerObject::MEDIA_TYPE_WEB_PAGE;
- mMedia->mPassedWhitelist = FALSE;
- }
- else if (mMedia->mMediaURL != media_url)
- {
- retval |= MEDIA_URL_UPDATED;
- mMedia->mMediaURL = media_url;
- mMedia->mPassedWhitelist = FALSE;
- }
- }
- else if (mMedia)
- {
- retval |= MEDIA_URL_REMOVED;
- delete mMedia;
- mMedia = NULL;
}
+ retval |= checkMediaURL(media_url);
//
// Unpack particle system data
@@ -3472,7 +3466,7 @@ U8 LLViewerObject::getMediaType() const
}
else
{
- return LLViewerObject::MEDIA_TYPE_NONE;
+ return LLViewerObject::MEDIA_NONE;
}
}
@@ -3734,16 +3728,13 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos
}
-void LLViewerObject::changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image)
+void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
{
- U32 end = getNumTEs() ;
- for (U32 face = 0 ; face < end ; face++)
+ if(index < 0 || index >= getNumTEs())
{
- if(old_image == mTEImages[face])
- {
- mTEImages[face] = new_image ;
- }
+ return ;
}
+ mTEImages[index] = new_image ;
}
S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 08e2ec47cd..bec36f9da7 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -158,10 +158,16 @@ public:
virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
// Types of media we can associate
- enum { MEDIA_TYPE_NONE = 0, MEDIA_TYPE_WEB_PAGE = 1 };
+ enum { MEDIA_NONE = 0, MEDIA_SET = 1 };
// Return codes for processUpdateMessage
- enum { MEDIA_URL_REMOVED = 0x1, MEDIA_URL_ADDED = 0x2, MEDIA_URL_UPDATED = 0x4, INVALID_UPDATE = 0x80000000 };
+ enum {
+ MEDIA_URL_REMOVED = 0x1,
+ MEDIA_URL_ADDED = 0x2,
+ MEDIA_URL_UPDATED = 0x4,
+ MEDIA_FLAGS_CHANGED = 0x8,
+ INVALID_UPDATE = 0x80000000
+ };
virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
@@ -318,7 +324,7 @@ public:
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*virtual*/ BOOL setMaterial(const U8 material);
virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
- void changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image) ;
+ void changeTEImage(S32 index, LLViewerTexture* new_image) ;
LLViewerTexture *getTEImage(const U8 te) const;
void fitFaceTexture(const U8 face);
@@ -504,6 +510,10 @@ private:
ExtraParameter* getExtraParameterEntry(U16 param_type) const;
ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
bool unpackParameterEntry(U16 param_type, LLDataPacker *dp);
+
+ // This function checks to see if the given media URL has changed its version
+ // and the update wasn't due to this agent's last action.
+ U32 checkMediaURL(const std::string &media_url);
public:
//
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 86d51bfd4b..a3f9c839a0 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -46,6 +46,7 @@
#include "llnotifications.h"
#include "llfirstuse.h"
#include "llpluginclassmedia.h"
+#include "llviewertexture.h"
// Static Variables
@@ -219,17 +220,25 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
// Delete the old one first so they don't fight over the texture.
sMediaImpl->stop();
- sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id,
- media_width, media_height, media_auto_scale,
+ sMediaImpl = LLViewerMedia::newMediaImpl(
+ placeholder_texture_id,
+ media_width,
+ media_height,
+ media_auto_scale,
media_loop);
+ sMediaImpl->navigateTo(media_url);
}
}
else
{
// There is no media impl, make a new one
- sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id,
- media_width, media_height, media_auto_scale,
+ sMediaImpl = LLViewerMedia::newMediaImpl(
+ placeholder_texture_id,
+ media_width,
+ media_height,
+ media_auto_scale,
media_loop);
+ sMediaImpl->navigateTo(media_url);
}
LLFirstUse::useMedia();
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index c5b09403cb..7ca11d8364 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -50,7 +50,6 @@
#include "llfirstuse.h"
#include "llfloaterbuyland.h"
#include "llfloatergroups.h"
-//#include "llfloaterhtml.h"
#include "llfloatersellland.h"
#include "llfloatertools.h"
#include "llnotify.h"
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 2c68a106c3..7ea55b49e8 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1428,6 +1428,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("EventQueueGet");
capabilityNames.append("FetchInventory");
capabilityNames.append("WebFetchInventoryDescendents");
+ capabilityNames.append("ObjectMedia");
+ capabilityNames.append("ObjectMediaNavigate");
capabilityNames.append("FetchLib");
capabilityNames.append("FetchLibDescendents");
capabilityNames.append("GroupProposalBallot");
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index e3d657068f..a2f6b70006 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -62,6 +62,10 @@
#include "llappviewer.h"
#include "lltextureatlas.h"
#include "lltextureatlasmanager.h"
+#include "lltextureentry.h"
+#include "llmediaentry.h"
+#include "llvovolume.h"
+#include "llviewermedia.h"
///////////////////////////////////////////////////////////////////////////////
// statics
@@ -114,45 +118,18 @@ LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id)
LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)
{
- LLViewerMediaTexture::media_map_t::iterator iter = LLViewerMediaTexture::sMediaMap.find(media_id);
- if(iter == LLViewerMediaTexture::sMediaMap.end())
- return NULL;
-
- ((LLViewerMediaTexture*)(iter->second))->getLastReferencedTimer()->reset() ;
- return iter->second;
+ return LLViewerMediaTexture::findMediaTexture(media_id) ;
}
LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
{
- LLViewerMediaTexture* tex = LLViewerTextureManager::findMediaTexture(id) ;
+ LLViewerMediaTexture* tex = LLViewerMediaTexture::findMediaTexture(id) ;
if(!tex)
{
tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image) ;
}
- LLViewerTexture* old_tex = tex->getOldTexture() ;
- if(!old_tex)
- {
- //if there is a fetched texture with the same id, replace it by this media texture
- old_tex = gTextureList.findImage(id) ;
- if(old_tex)
- {
- tex->setOldTexture(old_tex) ;
- }
- }
-
- if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable") && gSavedSettings.getBOOL("AudioStreamingVideo"))
- {
- if(!tex->isPlaying())
- {
- if(old_tex)
- {
- old_tex->switchToTexture(tex) ;
- }
- tex->setPlaying(TRUE) ;
- }
- }
- tex->getLastReferencedTimer()->reset() ;
+ tex->initVirtualSize() ;
return tex ;
}
@@ -303,7 +280,7 @@ void LLViewerTextureManager::cleanup()
LLViewerFetchedTexture::sMissingAssetImagep = NULL;
LLViewerFetchedTexture::sWhiteImagep = NULL;
- LLViewerMediaTexture::sMediaMap.clear() ;
+ LLViewerMediaTexture::cleanup() ;
}
//----------------------------------------------------------------------------------------------
@@ -437,6 +414,7 @@ void LLViewerTexture::init(bool firstinit)
mTextureState = NO_DELETE ;
mDontDiscard = FALSE;
mMaxVirtualSize = 0.f;
+ mNeedsResetMaxVirtualSize = FALSE ;
}
//virtual
@@ -538,33 +516,24 @@ void LLViewerTexture::resetTextureStats(BOOL zero)
}
}
+//virtual
+F32 LLViewerTexture::getMaxVirtualSize()
+{
+ return mMaxVirtualSize ;
+}
+
+//virtual
void LLViewerTexture::addFace(LLFace* facep)
{
mFaceList.push_back(facep) ;
}
+
+//virtual
void LLViewerTexture::removeFace(LLFace* facep)
{
mFaceList.remove(facep) ;
}
-void LLViewerTexture::switchToTexture(LLViewerTexture* new_texture)
-{
- if(this == new_texture)
- {
- return ;
- }
-
- new_texture->addTextureStats(getMaxVirtualSize()) ;
-
- for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); )
- {
- LLFace* facep = *iter++ ;
- facep->setTexture(new_texture) ;
- facep->getViewerObject()->changeTEImage(this, new_texture) ;
- gPipeline.markTextured(facep->getDrawable());
- }
-}
-
void LLViewerTexture::forceActive()
{
mTextureState = ACTIVE ;
@@ -613,7 +582,16 @@ BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* image
{
llassert_always(mGLTexturep.notNull()) ;
- return mGLTexturep->createGLTexture(discard_level, imageraw, usename) ;
+ BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename) ;
+
+ if(ret)
+ {
+ mFullWidth = mGLTexturep->getCurrentWidth() ;
+ mFullHeight = mGLTexturep->getCurrentHeight() ;
+ mComponents = mGLTexturep->getComponents() ;
+ }
+
+ return ret ;
}
void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
@@ -2142,18 +2120,59 @@ void LLViewerMediaTexture::updateClass()
for(media_map_t::iterator iter = sMediaMap.begin() ; iter != sMediaMap.end(); )
{
- LLViewerMediaTexture* mediap = iter->second;
- ++iter ;
+ LLViewerMediaTexture* mediap = iter->second;
+ //
+ //Note: delay some time to delete the media textures to stop endlessly creating and immediately removing media texture.
+ //
if(mediap->getNumRefs() == 1 && mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) //one by sMediaMap
{
- sMediaMap.erase(mediap->getID()) ;
+ media_map_t::iterator cur = iter++ ;
+ sMediaMap.erase(cur) ;
}
+ else
+ {
+ ++iter ;
+ }
+ }
+}
+
+//static
+void LLViewerMediaTexture::removeMediaImplFromTexture(const LLUUID& media_id)
+{
+ LLViewerMediaTexture* media_tex = findMediaTexture(media_id) ;
+ if(media_tex)
+ {
+ media_tex->invalidateMediaImpl() ;
}
}
+//static
+void LLViewerMediaTexture::cleanup()
+{
+ sMediaMap.clear() ;
+}
+
+//static
+LLViewerMediaTexture* LLViewerMediaTexture::findMediaTexture(const LLUUID& media_id)
+{
+ media_map_t::iterator iter = sMediaMap.find(media_id);
+ if(iter == sMediaMap.end())
+ {
+ return NULL;
+ }
+
+ LLViewerMediaTexture* media_tex = iter->second ;
+ media_tex->setMediaImpl() ;
+ media_tex->getLastReferencedTimer()->reset() ;
+
+ return media_tex;
+}
+
LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
- : LLViewerTexture(id, usemipmaps)
+ : LLViewerTexture(id, usemipmaps),
+ mMediaImplp(NULL),
+ mUpdateVirtualSizeTime(0)
{
sMediaMap.insert(std::make_pair(id, this));
@@ -2165,6 +2184,13 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ;
mIsPlaying = FALSE ;
+
+ setMediaImpl() ;
+}
+
+//virtual
+LLViewerMediaTexture::~LLViewerMediaTexture()
+{
}
void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */)
@@ -2172,7 +2198,6 @@ void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */)
mGLTexturep = NULL ;
init(false);
mUseMipMaps = usemipmaps ;
- mIsPlaying = FALSE ;
getLastReferencedTimer()->reset() ;
generateGLTexture() ;
@@ -2195,14 +2220,336 @@ S8 LLViewerMediaTexture::getType() const
return LLViewerTexture::MEDIA_TEXTURE ;
}
-void LLViewerMediaTexture::setOldTexture(LLViewerTexture* tex)
+void LLViewerMediaTexture::invalidateMediaImpl()
{
- mOldTexturep = tex ;
+ mMediaImplp = NULL ;
}
+
+void LLViewerMediaTexture::setMediaImpl()
+{
+ if(!mMediaImplp)
+ {
+ mMediaImplp = LLViewerMedia::getMediaImplFromTextureID(mID) ;
+ }
+}
+
+//return true if all faces to reference to this media texture are found
+//Note: mMediaFaceList is valid only for the current instant
+// because it does not check the face validity after the current frame.
+BOOL LLViewerMediaTexture::findFaces()
+{
+ mMediaFaceList.clear() ;
+
+ BOOL ret = TRUE ;
+
+ //for parcel media
+ LLViewerTexture* tex = gTextureList.findImage(mID) ;
+ if(tex)
+ {
+ const ll_face_list_t* face_list = tex->getFaceList() ;
+ for(ll_face_list_t::const_iterator iter = face_list->begin(); iter != face_list->end(); ++iter)
+ {
+ mMediaFaceList.push_back(*iter) ;
+ }
+ }
-LLViewerTexture* LLViewerMediaTexture::getOldTexture() const
+ if(!mMediaImplp)
+ {
+ return TRUE ;
+ }
+
+ //for media on a face.
+ const std::list< LLVOVolume* >* obj_list = mMediaImplp->getObjectList() ;
+ std::list< LLVOVolume* >::const_iterator iter = obj_list->begin() ;
+ for(; iter != obj_list->end(); ++iter)
+ {
+ LLVOVolume* obj = *iter ;
+ if(obj->mDrawable.isNull())
+ {
+ ret = FALSE ;
+ continue ;
+ }
+
+ S32 face_id = -1 ;
+ while((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp, face_id)) > -1)
+ {
+ LLFace* facep = obj->mDrawable->getFace(face_id) ;
+ if(facep)
+ {
+ mMediaFaceList.push_back(facep) ;
+ }
+ else
+ {
+ ret = FALSE ;
+ }
+ }
+ }
+
+ return ret ;
+}
+
+void LLViewerMediaTexture::initVirtualSize()
+{
+ if(mIsPlaying)
+ {
+ return ;
+ }
+
+ findFaces() ;
+ for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
+ {
+ addTextureStats((*iter)->getVirtualSize()) ;
+ }
+}
+
+void LLViewerMediaTexture::addMediaToFace(LLFace* facep)
+{
+ if(!mIsPlaying)
+ {
+ return ; //no need to add the face because the media is not in playing.
+ }
+
+ switchTexture(facep) ;
+}
+
+void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
+{
+ if(!mIsPlaying)
+ {
+ return ; //no need to remove the face because the media is not in playing.
+ }
+ if(!facep)
+ {
+ return ;
+ }
+
+ mIsPlaying = FALSE ; //set to remove the media from the face.
+ switchTexture(facep) ;
+ mIsPlaying = TRUE ; //set the flag back.
+
+ if(mFaceList.empty()) //no face referencing to this media
+ {
+ stopPlaying() ;
+ }
+}
+
+//virtual
+void LLViewerMediaTexture::addFace(LLFace* facep)
+{
+ LLViewerTexture::addFace(facep) ;
+
+ const LLTextureEntry* te = facep->getTextureEntry() ;
+ if(te)
+ {
+ LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
+ if(tex)
+ {
+ mTextureList.push_back(tex) ;//increase the reference number by one for tex to avoid deleting it.
+ return ;
+ }
+ }
+ llerrs << "The face does not have a valid texture before media texture." << llendl ;
+}
+
+//virtual
+void LLViewerMediaTexture::removeFace(LLFace* facep)
+{
+ LLViewerTexture::removeFace(facep) ;
+
+ const LLTextureEntry* te = facep->getTextureEntry() ;
+ if(te)
+ {
+ LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
+ if(tex)
+ {
+ for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
+ iter != mTextureList.end(); ++iter)
+ {
+ if(*iter == tex)
+ {
+ mTextureList.erase(iter) ; //decrease the reference number for tex by one.
+ return ;
+ }
+ }
+
+ //
+ //we have some trouble here: the texture of the face is changed.
+ //we need to find the former texture, and remove it from the list to avoid memory leaking.
+ if(mFaceList.empty())
+ {
+ mTextureList.clear() ;
+ return ;
+ }
+ S32 end = mFaceList.size() ;
+ std::vector<const LLTextureEntry*> te_list(end) ;
+ S32 i = 0 ;
+ for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+ {
+ te_list[i++] = (*iter)->getTextureEntry() ;//all textures are in use.
+ }
+ for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
+ iter != mTextureList.end(); ++iter)
+ {
+ for(i = 0 ; i < end ; i++)
+ {
+ if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use.
+ {
+ te_list[i] = NULL ;
+ break ;
+ }
+ }
+ if(i == end) //no hit for this texture, remove it.
+ {
+ mTextureList.erase(iter) ; //decrease the reference number for tex by one.
+ return ;
+ }
+ }
+ }
+ }
+ llerrs << "mTextureList texture reference number is corrupted." << llendl ;
+}
+
+void LLViewerMediaTexture::stopPlaying()
+{
+ if(mMediaImplp)
+ {
+ mMediaImplp->stop() ;
+ }
+ mIsPlaying = FALSE ;
+}
+
+void LLViewerMediaTexture::switchTexture(LLFace* facep)
+{
+ if(facep)
+ {
+ //check if another media is playing on this face.
+ if(facep->getTexture() && facep->getTexture() != this
+ && facep->getTexture()->getType() == LLViewerTexture::MEDIA_TEXTURE)
+ {
+ if(mID == facep->getTexture()->getID()) //this is a parcel media
+ {
+ return ; //let the prim media win.
+ }
+ }
+
+ if(mIsPlaying) //old textures switch to the media texture
+ {
+ facep->switchTexture(this) ;
+ }
+ else //switch to old textures.
+ {
+ const LLTextureEntry* te = facep->getTextureEntry() ;
+ if(te)
+ {
+ LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
+ facep->switchTexture(tex) ;
+ }
+ }
+ }
+}
+
+void LLViewerMediaTexture::setPlaying(BOOL playing)
{
- return mOldTexturep ;
+ if(!mMediaImplp)
+ {
+ return ;
+ }
+ if(!playing && !mIsPlaying)
+ {
+ return ; //media is already off
+ }
+
+ if(playing == mIsPlaying && !mMediaImplp->isUpdated())
+ {
+ return ; //nothing has changed since last time.
+ }
+
+ mIsPlaying = playing ;
+ if(mIsPlaying) //is about to play this media
+ {
+ if(findFaces())
+ {
+ //about to update all faces.
+ mMediaImplp->setUpdated(FALSE) ;
+ }
+
+ if(mMediaFaceList.empty())//no face pointing to this media
+ {
+ stopPlaying() ;
+ return ;
+ }
+
+ for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
+ {
+ switchTexture(*iter) ;
+ }
+ }
+ else //stop playing this media
+ {
+ if(mFaceList.empty())
+ {
+ return ;
+ }
+
+ ll_face_list_t::iterator cur ;
+ for(ll_face_list_t::iterator iter = mFaceList.begin(); iter!= mFaceList.end(); )
+ {
+ cur = iter++ ;
+ switchTexture(*cur) ; //cur could be removed in this function.
+ }
+ }
+ return ;
+}
+
+//virtual
+F32 LLViewerMediaTexture::getMaxVirtualSize()
+{
+ if(LLFrameTimer::getFrameCount() == mUpdateVirtualSizeTime)
+ {
+ return mMaxVirtualSize ;
+ }
+ mUpdateVirtualSizeTime = LLFrameTimer::getFrameCount() ;
+
+ if(mNeedsResetMaxVirtualSize)
+ {
+ mMaxVirtualSize = 0.f ;//reset
+ mNeedsResetMaxVirtualSize = FALSE ;
+ }
+
+ if(mIsPlaying) //media is playing
+ {
+ if(mFaceList.size() > 0)
+ {
+ for(std::list<LLFace*>::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+ {
+ LLFace* facep = *iter ;
+ if(facep->getDrawable()->isRecentlyVisible())
+ {
+ addTextureStats(facep->getVirtualSize()) ;
+ }
+ }
+ }
+ }
+ else //media is not in playing
+ {
+ findFaces() ;
+
+ if(!mMediaFaceList.empty())
+ {
+ for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
+ {
+ LLFace* facep = *iter ;
+ if(facep->getDrawable()->isRecentlyVisible())
+ {
+ addTextureStats(facep->getVirtualSize()) ;
+ }
+ }
+ }
+ }
+
+ mNeedsResetMaxVirtualSize = TRUE ;
+
+ return mMaxVirtualSize ;
}
//----------------------------------------------------------------------------------------------
//end of LLViewerMediaTexture
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 0be1bf81de..596bfea670 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -49,6 +49,7 @@
class LLFace;
class LLImageGL ;
+class LLViewerObject;
class LLViewerTexture;
class LLViewerFetchedTexture ;
class LLViewerMediaTexture ;
@@ -58,7 +59,9 @@ typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_
class LLVFile;
class LLMessageSystem;
-
+class LLViewerMediaImpl ;
+class LLVOVolume ;
+
class LLLoadedCallbackEntry
{
public:
@@ -123,6 +126,8 @@ public:
BOOST_MAX_LEVEL
};
+ typedef std::list<LLFace*> ll_face_list_t ;
+
protected:
virtual ~LLViewerTexture();
LOG_CLASS(LLViewerTexture);
@@ -152,16 +157,17 @@ public:
//maxVirtualSize of the texture
void addTextureStats(F32 virtual_size) const ;
void resetTextureStats(BOOL zero = FALSE);
- F32 getMaxVirtualSize()const {return mMaxVirtualSize ;}
+ virtual F32 getMaxVirtualSize() ;
LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;}
S32 getFullWidth() const { return mFullWidth; }
S32 getFullHeight() const { return mFullHeight; }
- void addFace(LLFace* facep) ;
- void removeFace(LLFace* facep) ;
-
+ virtual void addFace(LLFace* facep) ;
+ virtual void removeFace(LLFace* facep) ;
+ const ll_face_list_t* getFaceList() const {return &mFaceList ;}
+
void generateGLTexture() ;
void destroyGLTexture() ;
@@ -206,8 +212,6 @@ public:
//end of functions to access LLImageGL
//---------------------------------------------------------------------------------------------
- void switchToTexture(LLViewerTexture* new_texture) ; //make all faces pointing to this texture to point to new_texture.
-
//-----------------
/*virtual*/ void setActive() ;
void forceActive() ;
@@ -233,10 +237,9 @@ protected:
BOOL mUseMipMaps ;
S8 mComponents;
mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need?
-
+ mutable BOOL mNeedsResetMaxVirtualSize ;
LLFrameTimer mLastReferencedTimer;
- typedef std::list<LLFace*> ll_face_list_t ;
ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
//GL texture
@@ -498,34 +501,61 @@ private:
class LLViewerMediaTexture : public LLViewerTexture
{
protected:
- /*virtual*/ ~LLViewerMediaTexture() {}
+ /*virtual*/ ~LLViewerMediaTexture() ;
public:
LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
/*virtual*/ S8 getType() const;
-
void reinit(BOOL usemipmaps = TRUE);
BOOL getUseMipMaps() {return mUseMipMaps ; }
- void setUseMipMaps(BOOL mipmap) ;
+ void setUseMipMaps(BOOL mipmap) ;
+
+ void setPlaying(BOOL playing) ;
+ BOOL isPlaying() const {return mIsPlaying;}
+ void setMediaImpl() ;
- void setOldTexture(LLViewerTexture* tex) ;
- LLViewerTexture* getOldTexture() const ;
+ void initVirtualSize() ;
+ void invalidateMediaImpl() ;
- void setPlaying(BOOL playing) {mIsPlaying = playing ;}
- BOOL isPlaying() const {return mIsPlaying;}
+ void addMediaToFace(LLFace* facep) ;
+ void removeMediaFromFace(LLFace* facep) ;
+
+ /*virtual*/ void addFace(LLFace* facep) ;
+ /*virtual*/ void removeFace(LLFace* facep) ;
+
+ /*virtual*/ F32 getMaxVirtualSize() ;
+private:
+ void switchTexture(LLFace* facep) ;
+ BOOL findFaces() ;
+ void stopPlaying() ;
private:
- LLPointer<LLViewerTexture> mOldTexturep ; //the texture this media texture replaces.
+ //
+ //an instant list, recording all faces referencing or can reference to this media texture.
+ //NOTE: it is NOT thread safe.
+ //
+ std::list< LLFace* > mMediaFaceList ;
+
+ //an instant list keeping all textures which are replaced by the current media texture,
+ //is only used to avoid the removal of those textures from memory.
+ std::list< LLPointer<LLViewerTexture> > mTextureList ;
+
+ LLViewerMediaImpl* mMediaImplp ;
BOOL mIsPlaying ;
+ U32 mUpdateVirtualSizeTime ;
public:
static void updateClass() ;
+ static void cleanup() ;
-public:
+ static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ;
+ static void removeMediaImplFromTexture(const LLUUID& media_id) ;
+
+private:
typedef std::map< LLUUID, LLPointer<LLViewerMediaTexture> > media_map_t ;
- static media_map_t sMediaMap ;
+ static media_map_t sMediaMap ;
};
//just an interface class, do not create instance from this class.
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index d23f10f880..4a0efbaddc 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3223,9 +3223,9 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans
// assume that pickAsync put the results in the back of the mPicks list
if(mPicks.size() != 0)
{
- mLastPick = mPicks.back();
- mLastPick.fetchResults();
- mPicks.pop_back();
+ mLastPick = mPicks.back();
+ mLastPick.fetchResults();
+ mPicks.pop_back();
}
else
{
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 93cb0f0f45..e69779b2dc 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -46,6 +46,8 @@
#include "llvolumemessage.h"
#include "material_codes.h"
#include "message.h"
+#include "llmediadataresponder.h"
+#include "llpluginclassmedia.h" // for code in the mediaEvent handler
#include "object_flags.h"
#include "llagentconstants.h"
#include "lldrawable.h"
@@ -65,6 +67,10 @@
#include "llworld.h"
#include "llselectmgr.h"
#include "pipeline.h"
+#include "llsdutil.h"
+#include "llmediaentry.h"
+#include "llmediadatafetcher.h"
+#include "llagent.h"
const S32 MIN_QUIET_FRAMES_COALESCE = 30;
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
@@ -100,6 +106,8 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mLODChanged = FALSE;
mSculptChanged = FALSE;
mSpotLightPriority = 0.f;
+
+ mMediaImplList.resize(getNumTEs());
}
LLVOVolume::~LLVOVolume()
@@ -108,14 +116,31 @@ LLVOVolume::~LLVOVolume()
mTextureAnimp = NULL;
delete mVolumeImpl;
mVolumeImpl = NULL;
+
+ if(!mMediaImplList.empty())
+ {
+ for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
+ {
+ if(mMediaImplList[i].notNull())
+ {
+ mMediaImplList[i]->removeObject(this) ;
+ }
+ }
+ }
}
// static
void LLVOVolume::initClass()
{
+ LLMediaDataFetcher::initClass();
}
+// static
+void LLVOVolume::cleanupClass()
+{
+ LLMediaDataFetcher::cleanupClass();
+}
U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
@@ -123,6 +148,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
LLDataPacker *dp)
{
LLColor4U color;
+ const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
// Do base class updates...
U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
@@ -190,10 +216,15 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
//
// Unpack texture entry data
//
- if (unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num) & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR))
+ S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
+ if (result & teDirtyBits)
{
updateTEData();
}
+ if (result & TEM_CHANGE_MEDIA)
+ {
+ retval |= MEDIA_FLAGS_CHANGED;
+ }
}
else
{
@@ -226,9 +257,16 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
// llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl;
llwarns << "Bogus TE data in " << getID() << llendl;
}
- else if (res2 & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR))
+ else
{
- updateTEData();
+ if (res2 & teDirtyBits)
+ {
+ updateTEData();
+ }
+ if (res2 & TEM_CHANGE_MEDIA)
+ {
+ retval |= MEDIA_FLAGS_CHANGED;
+ }
}
U32 value = dp->getPassFlags();
@@ -266,14 +304,29 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
U8 tdpbuffer[1024];
LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024);
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num);
- if ( unpackTEMessage(tdp) & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR))
+ S32 result = unpackTEMessage(tdp);
+ if (result & teDirtyBits)
{
updateTEData();
}
+ if (result & TEM_CHANGE_MEDIA)
+ {
+ retval |= MEDIA_FLAGS_CHANGED;
+ }
}
}
}
-
+ if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED)) {
+ // If the media changed at all, request new media data
+ if(mMedia)
+ {
+ llinfos << "Media URL: " << mMedia->mMediaURL << llendl;
+ }
+ requestMediaDataUpdate();
+ }
+ // ...and clean up any media impls
+ cleanUpMediaImpls();
+
return retval;
}
@@ -1327,6 +1380,46 @@ BOOL LLVOVolume::isRootEdit() const
return TRUE;
}
+//virtual
+void LLVOVolume::setNumTEs(const U8 num_tes)
+{
+ const U8 old_num_tes = getNumTEs() ;
+
+ if(old_num_tes && old_num_tes < num_tes) //new faces added
+ {
+ LLViewerObject::setNumTEs(num_tes) ;
+
+ if(mMediaImplList.size() >= old_num_tes && mMediaImplList[old_num_tes -1].notNull())//duplicate the last media textures if exists.
+ {
+ mMediaImplList.resize(num_tes) ;
+ const LLTextureEntry* te = getTE(old_num_tes - 1) ;
+ for(U8 i = old_num_tes; i < num_tes ; i++)
+ {
+ setTE(i, *te) ;
+ mMediaImplList[i] = mMediaImplList[old_num_tes -1] ;
+ }
+ mMediaImplList[old_num_tes -1]->setUpdated(TRUE) ;
+ }
+ }
+ else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed
+ {
+ U8 end = mMediaImplList.size() ;
+ for(U8 i = num_tes; i < end ; i++)
+ {
+ removeMediaImpl(i) ;
+ }
+ mMediaImplList.resize(num_tes) ;
+
+ LLViewerObject::setNumTEs(num_tes) ;
+ }
+ else
+ {
+ LLViewerObject::setNumTEs(num_tes) ;
+ }
+
+ return ;
+}
+
void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep)
{
BOOL changed = (mTEImages[te] != imagep);
@@ -1510,6 +1603,321 @@ void LLVOVolume::updateTEData()
}*/
}
+bool LLVOVolume::hasMedia() const
+{
+ bool result = false;
+ const U8 numTEs = getNumTEs();
+ for (U8 i = 0; i < numTEs; i++)
+ {
+ const LLTextureEntry* te = getTE(i);
+ if(te->hasMedia())
+ {
+ result = true;
+ break;
+ }
+ }
+ return result;
+}
+
+void LLVOVolume::requestMediaDataUpdate()
+{
+ LLMediaDataFetcher::fetchMedia(this);
+}
+
+void LLVOVolume::cleanUpMediaImpls()
+{
+ // Iterate through our TEs and remove any Impls that are no longer used
+ const U8 numTEs = getNumTEs();
+ for (U8 i = 0; i < numTEs; i++)
+ {
+ const LLTextureEntry* te = getTE(i);
+ if( ! te->hasMedia())
+ {
+ // Delete the media IMPL!
+ removeMediaImpl(i) ;
+ }
+ }
+}
+
+void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array)
+{
+ // media_data_array is an array of media entry maps
+
+ //llinfos << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << llendl;
+
+ LLSD::array_const_iterator iter = media_data_array.beginArray();
+ LLSD::array_const_iterator end = media_data_array.endArray();
+ U8 texture_index = 0;
+ for (; iter != end; ++iter, ++texture_index)
+ {
+ syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/);
+ }
+}
+
+void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool merge, bool ignore_agent)
+{
+ LLTextureEntry *te = getTE(texture_index);
+ //llinfos << "BEFORE: texture_index = " << texture_index
+ // << " hasMedia = " << te->hasMedia() << " : "
+ // << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;
+
+ std::string previous_url;
+ LLMediaEntry* mep = te->getMediaData();
+ if(mep)
+ {
+ // Save the "current url" from before the update so we can tell if
+ // it changes.
+ previous_url = mep->getCurrentURL();
+ }
+
+ if (merge)
+ {
+ te->mergeIntoMediaData(media_data);
+ }
+ else {
+ // XXX Question: what if the media data is undefined LLSD, but the
+ // update we got above said that we have media flags?? Here we clobber
+ // that, assuming the data from the service is more up-to-date.
+ te->updateMediaData(media_data);
+ }
+
+ mep = te->getMediaData();
+ if(mep)
+ {
+ bool update_from_self = false;
+ if (!ignore_agent)
+ {
+ LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL());
+ update_from_self = (updating_agent == gAgent.getID());
+ }
+ viewer_media_t media_impl = LLViewerMedia::updateMediaImpl(mep, previous_url, update_from_self);
+
+ addMediaImpl(media_impl, texture_index) ;
+ }
+
+ //llinfos << "AFTER: texture_index = " << texture_index
+ // << " hasMedia = " << te->hasMedia() << " : "
+ // << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;
+}
+
+void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event)
+{
+ switch(event)
+ {
+
+ case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED:
+ {
+ switch(impl->getNavState())
+ {
+ case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED:
+ {
+ // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast.
+
+ bool block_navigation = false;
+ // FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed
+ // to deal with multiple face indices.
+ int face_index = getFaceIndexWithMediaImpl(impl, -1);
+ std::string new_location = plugin->getLocation();
+
+ // Find the media entry for this navigate
+ LLMediaEntry* mep = NULL;
+ LLTextureEntry *te = getTE(face_index);
+ if(te)
+ {
+ mep = te->getMediaData();
+ }
+
+ if(mep)
+ {
+ if(!mep->checkCandidateUrl(new_location))
+ {
+ block_navigation = true;
+ }
+ }
+ else
+ {
+ llwarns << "Couldn't find media entry!" << llendl;
+ }
+
+ if(block_navigation)
+ {
+ llinfos << "blocking navigate to URI " << new_location << llendl;
+
+ // "bounce back" to the current URL from the media entry
+ // NOTE: the only way block_navigation can be true is if we found the media entry, so we're guaranteed here that mep is not NULL.
+ impl->navigateTo(mep->getCurrentURL());
+ }
+ else
+ {
+
+ llinfos << "broadcasting navigate with URI " << new_location << llendl;
+
+ // Post the navigate to the cap
+ std::string cap = getRegion()->getCapability("ObjectMediaNavigate");
+ if(cap.empty())
+ {
+ // XXX *TODO: deal with no cap! It may happen! (retry?)
+ LL_WARNS("Media") << "Can't broadcast navigate event -- ObjectMediaNavigate cap is not available" << LL_ENDL;
+ return;
+ }
+
+ // If we got here, the cap is available. Index through all faces that have this media and send the navigate message.
+ LLSD sd;
+ sd["object_id"] = mID;
+ sd["current_url"] = new_location;
+ sd["texture_index"] = face_index;
+ LLHTTPClient::post(cap, sd, new LLMediaDataResponder("ObjectMediaNavigate", sd, this));
+ }
+ }
+ break;
+
+ case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED:
+ // This is the first location changed event after the start of a server-directed nav. Don't broadcast it.
+ llinfos << " NOT broadcasting navigate (server-directed)" << llendl;
+ break;
+
+ default:
+ // This is a subsequent location-changed due to a redirect. Don't broadcast.
+ llinfos << " NOT broadcasting navigate (redirect)" << llendl;
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+void LLVOVolume::sendMediaDataUpdate() const
+{
+ std::string url = getRegion()->getCapability("ObjectMedia");
+ if (!url.empty())
+ {
+ LLSD sd_payload;
+ sd_payload["verb"] = "UPDATE";
+ sd_payload[LLTextureEntry::OBJECT_ID_KEY] = mID;
+ LLSD object_media_data;
+ for (int i=0; i < getNumTEs(); i++) {
+ LLTextureEntry *texture_entry = getTE(i);
+ llassert((texture_entry->getMediaData() != NULL) == texture_entry->hasMedia());
+ const LLSD &media_data =
+ (texture_entry->getMediaData() == NULL) ? LLSD() : texture_entry->getMediaData()->asLLSD();
+ object_media_data.append(media_data);
+ }
+ sd_payload[LLTextureEntry::OBJECT_MEDIA_DATA_KEY] = object_media_data;
+
+ llinfos << "Sending media data: " << getID() << " " << ll_pretty_print_sd(sd_payload) << llendl;
+
+ LLHTTPClient::post(url, sd_payload, new LLMediaDataResponder("ObjectMedia", sd_payload, this));
+ }
+ // XXX *TODO: deal with no cap! It may happen! (retry?)
+}
+
+void LLVOVolume::removeMediaImpl(S32 texture_index)
+{
+ if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull())
+ {
+ return ;
+ }
+
+ //make the face referencing to mMediaImplList[texture_index] to point back to the old texture.
+ if(mDrawable)
+ {
+ LLFace* facep = mDrawable->getFace(texture_index) ;
+ if(facep)
+ {
+ LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
+ if(media_tex)
+ {
+ media_tex->removeMediaFromFace(facep) ;
+ }
+ }
+ }
+
+ //check if some other face(s) of this object reference(s)to this media impl.
+ S32 i ;
+ S32 end = (S32)mMediaImplList.size() ;
+ for(i = 0; i < end ; i++)
+ {
+ if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index])
+ {
+ break ;
+ }
+ }
+
+ if(i == end) //this object does not need this media impl.
+ {
+ mMediaImplList[texture_index]->removeObject(this) ;
+ }
+
+ mMediaImplList[texture_index] = NULL ;
+ return ;
+}
+
+void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index)
+{
+ if((S32)mMediaImplList.size() < texture_index + 1)
+ {
+ mMediaImplList.resize(texture_index + 1) ;
+ }
+
+ if(mMediaImplList[texture_index].notNull())
+ {
+ if(mMediaImplList[texture_index] == media_impl)
+ {
+ return ;
+ }
+
+ removeMediaImpl(texture_index) ;
+ }
+
+ mMediaImplList[texture_index] = media_impl;
+ media_impl->addObject(this) ;
+
+ //add the face to show the media if it is in playing
+ if(mDrawable)
+ {
+ LLFace* facep = mDrawable->getFace(texture_index) ;
+ if(facep)
+ {
+ LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
+ if(media_tex)
+ {
+ media_tex->addMediaToFace(facep) ;
+ }
+ }
+ else //the face is not available now, start media on this face later.
+ {
+ media_impl->setUpdated(TRUE) ;
+ }
+ }
+ return ;
+}
+
+viewer_media_t LLVOVolume::getMediaImpl(U8 face_id) const
+{
+ if(mMediaImplList.size() > face_id)
+ {
+ return mMediaImplList[face_id];
+ }
+ return NULL;
+}
+
+S32 LLVOVolume::getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id)
+{
+ S32 end = (S32)mMediaImplList.size() ;
+ for(S32 face_id = start_face_id + 1; face_id < end; face_id++)
+ {
+ if(mMediaImplList[face_id] == media_impl)
+ {
+ return face_id ;
+ }
+ }
+ return -1 ;
+}
+
//----------------------------------------------------------------------------
void LLVOVolume::setLightTextureID(LLUUID id)
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 1b90219836..9a79b620d5 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -35,6 +35,7 @@
#include "llviewerobject.h"
#include "llviewertexture.h"
+#include "llviewermedia.h"
#include "llframetimer.h"
#include "llapr.h"
#include "m3math.h" // LLMatrix3
@@ -45,6 +46,8 @@ class LLViewerTextureAnim;
class LLDrawPool;
class LLSelectNode;
+typedef std::vector<viewer_media_t> media_list_t;
+
enum LLVolumeInterfaceType
{
INTERFACE_FLEXIBLE = 1,
@@ -75,12 +78,14 @@ public:
// Class which embodies all Volume objects (with pcode LL_PCODE_VOLUME)
class LLVOVolume : public LLViewerObject
{
+ LOG_CLASS(LLVOVolume);
protected:
virtual ~LLVOVolume();
public:
static void initClass();
- static void preUpdateGeom();
+ static void cleanupClass();
+ static void preUpdateGeom();
enum
{
@@ -153,6 +158,7 @@ public:
/*virtual*/ void setScale(const LLVector3 &scale, BOOL damped);
+ /*virtual*/ void setNumTEs(const U8 num_tes);
/*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
@@ -224,13 +230,31 @@ public:
BOOL isVolumeGlobal() const;
BOOL canBeFlexible() const;
BOOL setIsFlexible(BOOL is_flexible);
-
+
+ void updateObjectMediaData(const LLSD &media_data_duples);
+ void mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event);
+
+ // Sync the given media data with the impl and the given te
+ void syncMediaData(S32 te, const LLSD &media_data, bool merge, bool ignore_agent);
+
+ // Send media data update to the simulator.
+ void sendMediaDataUpdate() const;
+
+ viewer_media_t getMediaImpl(U8 face_id) const;
+ S32 getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id);
+
+ bool hasMedia() const;
+
protected:
S32 computeLODDetail(F32 distance, F32 radius);
BOOL calcLOD();
LLFace* addFace(S32 face_index);
void updateTEData();
+ void requestMediaDataUpdate();
+ void cleanUpMediaImpls();
+ void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;
+ void removeMediaImpl(S32 texture_index) ;
public:
LLViewerTextureAnim *mTextureAnimp;
U8 mTexAnimMode;
@@ -251,6 +275,7 @@ private:
LLVolumeInterface *mVolumeImpl;
LLPointer<LLViewerFetchedTexture> mSculptTexture;
LLPointer<LLViewerFetchedTexture> mLightTexture;
+ media_list_t mMediaImplList;
// statics
public:
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index da1cd59619..7e22e17188 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -94,7 +94,7 @@
value="0.58 0.66 0.84 1" />
<color
name="AvatarNameColor"
- value="0.98 0.69 0.36 1" />
+ reference="White" />
<color
name="BackgroundChatColor"
reference="DkGray_66" />
@@ -253,7 +253,7 @@
reference="White_10" />
<color
name="DefaultHighlightLight"
- reference="White_25" />
+ reference="White_25" />
<color
name="DefaultShadowDark"
reference="Black_50" />
@@ -493,7 +493,7 @@
value="0 0.78 0.78 1" />
<color
name="NotifyBoxColor"
- value="0.27 0.67 1 1" />
+ value="LtGray" />
<color
name="NotifyCautionBoxColor"
value="1 0.82 0.46 1" />
@@ -625,7 +625,7 @@
reference="Black" />
<color
name="TextDefaultColor"
- value="0 0 0 .33" />
+ value="Black" />
<color
name="TextEmbeddedItemColor"
value="0 0 0.5 1" />
@@ -643,16 +643,16 @@
value="0 0 0 .33" />
<color
name="TimeTextColor"
- reference="LtGray" />
+ reference="LtGray_50" />
<color
name="TitleBarFocusColor"
reference="White_10" />
<color
name="ToolTipBgColor"
- value="0 0 0 .75" />
+ value="DkGray" />
<color
name="ToolTipBorderColor"
- value="0 0 0 .75" />
+ value="White_50" />
<color
name="ToolTipTextColor"
reference="LtGray" />
diff --git a/indra/newview/skins/default/html/en-us/help-offline/index.html b/indra/newview/skins/default/html/en-us/help-offline/index.html
new file mode 100644
index 0000000000..bf3677603e
--- /dev/null
+++ b/indra/newview/skins/default/html/en-us/help-offline/index.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Offline Help</title>
+<style>
+body {background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;width:100%;padding:0px;margin:0px;}
+a {color:#93a9d5;}
+a:active {color:#50607C;text-decoration:underline;}
+a:hover {color:#ff7900;text-decoration:underline;}
+#infobox{position:absolute;top:40%;left:50%;z-index:1;padding:0;width:592px;margin-left:-296px;margin-top:-150px;text-align:center;font-size:1.2em; color:#ccc;}
+#infobox #submitbtn {padding:15px 3px 5px 15px;height:28px;width:127px;margin-left:244px;}
+#infobox #submitbtn input {text-transform:capitalize;color:#fff;font-size:1.0em;height:28px;width:127px;border:none;font-weight:normal;background:url(../../btn_purplepill_bg.png) bottom left no-repeat;vertical-align:text-bottom;font-weight:bold;}
+#infobox #submitbtn input:hover.input_over, #login_box #submitbtn input:hover.input_off {color:#fff;border:none;background:url(../../btn_purplepill_bg.png) bottom right no-repeat;}
+#infobox #submitbtn input:active.input_over {color:#fff;border:none;background:url(../../btn_purplepill_bg.png) top left no-repeat;}
+#infobox #submitbtn input.pressed {color:#888;border:none;background:url(../../btn_purplepill_bg.png) top right no-repeat;}
+</style>
+</head>
+<body>
+<div id="infobox">
+ <p>
+ Second Life Offline Help.
+ </p>
+ <p>
+ You are not online and are configured not to fetch help remotely. This is all the help that is available
+ until more stuff is done. Yeah.
+ </p>
+ </div>
+</div>
+</body>
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 46c294768d..8a6e9486a2 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -110,12 +110,10 @@
<texture name="Home_Off" file_name="navbar/Home_Off.png" preload="false" />
<texture name="Home_Press" file_name="navbar/Home_Press.png" preload="false" />
- <texture name="Icon_Close_Background" file_name="windows/Icon_Close_Background.png" preload="true" />
<texture name="Icon_Close_Foreground" file_name="windows/Icon_Close_Foreground.png" preload="true" />
<texture name="Icon_Close_Press" file_name="windows/Icon_Close_Press.png" preload="true" />
<texture name="Icon_Close_Toast" file_name="windows/Icon_Close_Toast.png" preload="true" />
- <texture name="Icon_Dock_Background" file_name="windows/Icon_Dock_Background.png" preload="true" />
<texture name="Icon_Dock_Foreground" file_name="windows/Icon_Dock_Foreground.png" preload="true" />
<texture name="Icon_Dock_Press" file_name="windows/Icon_Dock_Press.png" preload="true" />
@@ -125,16 +123,16 @@
<texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="false" />
<texture name="Icon_Gear_Press" file_name="windows/Icon_Gear_Press.png" preload="false" />
- <texture name="Icon_Help_Background" file_name="windows/Icon_Help_Background.png" preload="false" />
<texture name="Icon_Help_Foreground" file_name="windows/Icon_Help_Foreground.png" preload="false" />
<texture name="Icon_Help_Press" file_name="windows/Icon_Help_Press.png" preload="false" />
<texture name="Icon_Info" file_name="windows/Icon_Info.png" preload="false" />
- <texture name="Icon_Minimize_Background" file_name="windows/Icon_Minimize_Background.png" preload="true" />
<texture name="Icon_Minimize_Foreground" file_name="windows/Icon_Minimize_Foreground.png" preload="true" />
<texture name="Icon_Minimize_Press" file_name="windows/Icon_Minimize_Press.png" preload="true" />
- <texture name="Icon_Undock_Background" file_name="windows/Icon_Undock_Background.png" preload="false" />
+ <texture name="Icon_Restore_Foreground" file_name="windows/Icon_Restore_Foreground.png" preload="false" />
+ <texture name="Icon_Restore_Press" file_name="windows/Icon_Restore_Press.png" preload="false" />
+
<texture name="Icon_Undock_Foreground" file_name="windows/Icon_Undock_Foreground.png" preload="false" />
<texture name="Icon_Undock_Press" file_name="windows/Icon_Undock_Press.png" preload="false" />
@@ -175,6 +173,9 @@
<texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" />
<texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" />
+ <texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/>
+ <texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/>
+
<texture name="ListItem_Select" file_name="widgets/ListItem_Select.png" preload="true" />
<texture name="ListItem_Over" file_name="widgets/ListItem_Over.png" preload="true" />
@@ -442,8 +443,6 @@
<texture name="cam_zoom_plus_in.tga" preload="false" />
<texture name="cam_zoom_minus_in.tga" preload="false" />
- <texture name="close_inactive_blue.tga" />
- <texture name="closebox.tga" />
<texture name="icn_clear_lineeditor.tga" />
<texture name="icn_chatbar.tga" />
@@ -493,10 +492,6 @@
<texture name="up_arrow.tga" file_name="up_arrow.png" />
<texture name="down_arrow.tga" file_name="down_arrow.png" />
- <texture name="restore_inactive.tga" />
- <texture name="restore.tga" />
- <texture name="restore_pressed.tga" />
-
<texture name="tearoffbox.tga" />
<texture name="tearoff_pressed.tga" />
diff --git a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png
new file mode 100644
index 0000000000..a1f21e8194
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png
new file mode 100644
index 0000000000..a1d602f6f0
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png
new file mode 100644
index 0000000000..1e753aaf1d
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png b/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png
new file mode 100644
index 0000000000..be66b05230
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 97afe6d324..c9e143bf95 100644
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -3,6 +3,7 @@
height="440"
layout="topleft"
name="floater_about"
+ help_topic="floater_about"
save_rect="true"
title="About [APP_NAME]"
width="470">
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
index 52c7944ba9..991c9a84a3 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
@@ -1,296 +1,291 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<floater
can_minimize="false"
- height="270"
+ height="275"
layout="topleft"
name="buy currency"
- help_topic="buy_currency"
+ help_topic="buy_linden_dollars"
single_instance="true"
- title="Buy Currency"
+ title="Buy L$"
width="350">
<floater.string
name="buy_currency">
- Buy L$ [LINDENS] for approx. US$ [USD]
+ Buy L$ [LINDENS] for approx. [LOCALAMOUNT]
</floater.string>
- <text
+ <floater.string
+ name="account_website">
+ http://secondlife.com/account/billing.php
+ </floater.string>
+ <icon
+ height="215"
+ image_name="Linden_Dollar_Background"
+ layout="topleft"
+ left="0"
+ name="normal_background"
+ top="17"
+ width="350" />
+ <text
type="string"
length="1"
- bottom_delta="48"
follows="top|left"
font="SansSerifHuge"
- height="24"
layout="topleft"
- left="16"
- name="info_buying"
- right="-20">
- Buying Currency:
+ left="20"
+ height="30"
+ top="30"
+ width="300"
+ name="info_need_more">
+ You need more L$:
</text>
<text
type="string"
length="1"
- bottom_delta="0"
follows="top|left"
- font="SansSerifHuge"
- height="24"
+ height="16"
layout="topleft"
- left="16"
- name="info_cannot_buy"
- right="-20">
- Cannot buy now:
+ left="20"
+ width="300"
+ name="contacting">
+ Contacting LindeX...
</text>
<text
type="string"
length="1"
- bottom_delta="0"
follows="top|left"
font="SansSerifHuge"
- height="24"
layout="topleft"
- left="16"
- name="info_need_more"
- right="-20">
- You need more currency:
+ left="20"
+ height="30"
+ top="30"
+ width="200"
+ name="info_buying">
+ Buy L$
</text>
- <icon
- follows="top|left"
- height="64"
- image_name="badge_note.j2c"
- layout="topleft"
- left="0"
- name="step_error"
- top="48"
- width="64" />
<text
type="string"
length="1"
- bottom_delta="96"
- follows="top|left"
- height="140"
- layout="topleft"
- left="72"
- name="error_message"
- right="-20">
- Something ain&apos;t right.
- </text>
- <button
- follows="bottom|left"
- height="20"
- label="Go to website"
- layout="topleft"
- left_delta="0"
- name="error_web"
- top_delta="124"
- width="120" />
- <icon
- follows="top|left"
- height="64"
- image_name="badge_note.j2c"
- layout="topleft"
- left="0"
- name="step_1"
- top="48"
- width="64" />
- <text
- type="string"
- length="1"
- bottom_delta="-38"
follows="top|left"
+ font="SansSerifMedium"
height="16"
layout="topleft"
- left="72"
- name="contacting"
- right="-20">
- Contacting LindeX...
+ left="20"
+ name="balance_label"
+ top_pad="10"
+ width="210">
+ I have
</text>
<text
type="string"
length="1"
- bottom_delta="0"
+ font="SansSerifMedium"
follows="top|left"
+ halign="right"
height="16"
layout="topleft"
- left="72"
- name="buy_action_unknown"
- right="-20">
- Buy L$ on the LindeX currency exchange
+ left="200"
+ name="balance_amount"
+ top_delta="0"
+ width="100">
+ L$ [AMT]
</text>
<text
type="string"
length="1"
- bottom_delta="0"
follows="top|left"
+ font="SansSerifMedium"
height="16"
+ top_pad="15"
layout="topleft"
- left="72"
- name="buy_action"
- right="-20">
- [NAME] L$ [PRICE]
+ left="20"
+ name="currency_action"
+ width="210">
+ I want to buy
</text>
<text
+ font="SansSerifMedium"
type="string"
length="1"
- follows="top|left"
+ follows="left|top"
height="16"
layout="topleft"
- left_delta="0"
- name="currency_action"
- top_pad="4"
- width="40">
- Buy L$
+ top_delta="0"
+ left="222"
+ name="currency_label"
+ width="15">
+ L$
</text>
<line_editor
type="string"
- length="1"
- follows="top|right"
- height="16"
- layout="topleft"
- left_pad="5"
+ halign="right"
+ font="SansSerifMedium"
+ select_on_focus="true"
+ follows="top|left"
+ top_delta="-7"
+ height="22"
+ label="L$"
+ left_pad="3"
name="currency_amt"
- top_delta="0"
- width="80">
+ width="60">
1234
</line_editor>
<text
type="string"
- length="1"
- follows="top|right"
- height="16"
- layout="topleft"
- left_pad="5"
- name="currency_est"
- top_delta="0"
- width="180">
- for approx. US$ [USD,number,2]
- </text>
- <text
- type="string"
- length="1"
- follows="top|right"
- height="16"
- layout="topleft"
- left_delta="5"
- name="getting_data"
- top_delta="0"
- width="180">
- Getting data...
- </text>
- <text
- type="string"
+ font="SansSerifMedium"
length="1"
follows="top|left"
height="16"
layout="topleft"
- left="80"
- name="balance_label"
- top="110"
- width="240">
- You currently have
+ left="20"
+ top_pad="10"
+ name="buying_label"
+ width="210">
+ For the price
</text>
<text
type="string"
length="1"
+ font="SansSerifMedium"
+ text_color="EmphasisColor"
follows="top|left"
halign="right"
height="16"
- layout="topleft"
- left_delta="0"
- name="balance_amount"
top_delta="0"
- width="240">
- L$ [AMT]
+ layout="topleft"
+ left="170"
+ name="currency_est"
+ width="130">
+ [LOCALAMOUNT]
</text>
<text
type="string"
+ font="SansSerifSmall"
+ text_color="EmphasisColor"
length="1"
follows="top|left"
height="16"
layout="topleft"
- left_delta="0"
- name="buying_label"
- top_pad="4"
- width="240">
- You are buying
+ left="40"
+ width="100"
+ halign="right"
+ name="getting_data">
+ Estimating...
</text>
<text
type="string"
+ font="SansSerifSmall"
+ top_delta="0"
length="1"
follows="top|left"
halign="right"
height="16"
+ left_pad="10"
+ width="150"
layout="topleft"
- left_delta="0"
- name="buying_amount"
- top_delta="0"
- width="240">
- L$ [AMT]
+ name="buy_action">
+ [NAME] L$ [PRICE]
</text>
<text
type="string"
+ font="SansSerifMedium"
length="1"
follows="top|left"
height="16"
layout="topleft"
- left_delta="0"
+ left="20"
name="total_label"
- top_pad="4"
- width="240">
- Your balance will be
+ width="210">
+ My new balance will be
</text>
<text
type="string"
length="1"
+ font="SansSerifMedium"
follows="top|left"
- halign="right"
+ top_delta="0"
height="16"
layout="topleft"
- left_delta="0"
+ left="200"
+ halign="right"
name="total_amount"
- top_delta="0"
- width="240">
+ width="100">
L$ [AMT]
</text>
<text
type="string"
length="1"
- bottom_delta="48"
follows="top|left"
- height="32"
layout="topleft"
- left="72"
- name="purchase_warning_repurchase"
- right="-20">
- Confirming this purchase only buys the currency.
-You&apos;ll need to try the operation again.
+ left="20"
+ width="300"
+ name="purchase_warning_repurchase">
+ Confirming this purchase only buys the L$.
+You&apos;ll need to try again.
</text>
<text
type="string"
length="1"
- bottom_delta="0"
follows="top|left"
- height="32"
layout="topleft"
- left="72"
- name="purchase_warning_notenough"
- right="-20">
- You aren&apos;t buying enough currency
+ left="20"
+ name="purchase_warning_notenough">
+ You aren&apos;t buying enough L$.
Increase the amount to buy.
</text>
+
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Buy Now"
+ layout="topleft"
+ left="151"
+ name="buy_btn"
+ top="248"
+ width="90"/>
<button
follows="bottom|right"
height="20"
label="Cancel"
layout="topleft"
- left="237"
+ left_pad="10"
name="cancel_btn"
- top="234"
- width="90" />
- <button
- follows="bottom|left"
- height="20"
- label="Purchase"
+ width="90"/>
+ <icon
+ height="215"
+ image_name="Linden_Dollar_Alert"
layout="topleft"
- left_delta="-96"
- name="buy_btn"
- top_delta="0"
- width="90" />
+ left="0"
+ name="error_background"
+ top="15"
+ width="350"/>
+ <text
+ type="string"
+ font="SansSerifHuge"
+ left="170"
+ width="170"
+ height="80"
+ top="30"
+ name="info_cannot_buy">
+ Take your
+[SECOND_LIFE] to
+the next level...
+ </text>
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Continue to the Web"
+ layout="topleft"
+ left="170"
+ name="error_web"
+ top="120"
+ width="160"/>
+ <text
+ type="string"
+ width="350"
+ height="20"
+ top_pad="92"
+ left_pad="-300"
+ follows="bottom|right"
+ name="cannot_buy_message">
+ Continue to the web site and enter payment information
+ </text>
</floater>
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 a1265d49f9..512b4c85a1 100644
--- a/indra/newview/skins/default/xui/en/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
can_resize="true"
- height="440"
+ height="400"
layout="topleft"
min_height="140"
min_width="467"
@@ -9,8 +9,8 @@
help_topic="floater_help_browser"
save_rect="true"
single_instance="true"
- title="Holy Bananas, it's the Help Browser"
- width="820">
+ title="Help Browser"
+ width="620">
<floater.string
name="home_page_url">
http://www.secondlife.com
@@ -20,150 +20,13 @@
http://support.secondlife.com
</floater.string>
<layout_stack
- bottom="440"
+ bottom="400"
follows="left|right|top|bottom"
layout="topleft"
left="10"
name="stack1"
top="20"
- width="800">
- <layout_panel
- auto_resize="false"
- height="20"
- layout="topleft"
- left="0"
- name="nav_controls"
- top="400"
- user_resize="false"
- width="800">
- <button
- follows="left|top"
- height="20"
- label="Back"
- layout="topleft"
- left="0"
- name="back"
- top="0"
- width="55" />
- <button
- follows="left|top"
- height="20"
- label="Forward"
- layout="topleft"
- left_pad="3"
- name="forward"
- top_delta="0"
- width="68" />
- <button
- enabled="false"
- follows="left|top"
- height="20"
- label="Reload"
- layout="topleft"
- left_pad="2"
- name="reload"
- top_delta="0"
- width="70"/>
- <combo_box
- allow_text_entry="true"
- follows="left|top|right"
- height="20"
- layout="topleft"
- left_pad="5"
- max_chars="255"
- name="address"
- top_delta="0"
- width="540" />
- <button
- enabled="false"
- follows="right|top"
- height="20"
- label="Go"
- layout="topleft"
- left_pad="5"
- name="go"
- top_delta="0"
- width="55" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- height="20"
- layout="topleft"
- left_delta="0"
- name="time_controls"
- top_delta="0"
- user_resize="false"
- width="800">
- <button
- follows="left|top"
- height="20"
- label="rewind"
- layout="topleft"
- left="0"
- name="rewind"
- top="0"
- width="55" />
- <button
- follows="left|top"
- height="20"
- image_selected="button_anim_play_selected.tga"
- image_unselected="button_anim_play.tga"
- layout="topleft"
- left_delta="55"
- name="play"
- picture_style="true"
- top_delta="0"
- width="55" />
- <button
- follows="left|top"
- height="20"
- image_selected="button_anim_pause_selected.tga"
- image_unselected="button_anim_pause.tga"
- layout="topleft"
- left_delta="0"
- name="pause"
- picture_style="true"
- top_delta="0"
- width="55" />
- <button
- follows="left|top"
- height="20"
- label="stop"
- layout="topleft"
- left_pad="10"
- name="stop"
- top_delta="0"
- width="55" />
- <button
- follows="left|top"
- height="20"
- label="forward"
- layout="topleft"
- left_pad="20"
- name="seek"
- top_delta="0"
- width="55" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- height="20"
- layout="topleft"
- left_delta="0"
- name="parcel_owner_controls"
- top_delta="0"
- user_resize="false"
- width="540">
- <button
- enabled="false"
- follows="left|top"
- height="20"
- label="Send Current URL to Parcel"
- layout="topleft"
- left="0"
- name="assign"
- top="0"
- width="200" />
- </layout_panel>
+ width="600">
<layout_panel
height="20"
layout="topleft"
@@ -171,7 +34,7 @@
name="external_controls"
top_delta="0"
user_resize="false"
- width="540">
+ width="570">
<web_browser
bottom="-10"
follows="left|right|top|bottom"
@@ -179,7 +42,7 @@
left="0"
name="browser"
top="0"
- width="540" />
+ width="570" />
<button
follows="bottom|left"
height="20"
@@ -189,25 +52,17 @@
name="open_browser"
top_pad="5"
width="185" />
- <check_box
- control_name="UseExternalBrowser"
- follows="bottom|left"
- height="20"
- label="Always open in my web browser"
- layout="topleft"
- left_pad="5"
- name="open_always"
- top_delta="0"
- width="200" />
+<!--
<button
follows="bottom|right"
height="20"
label="Close"
layout="topleft"
- left_pad="80"
+ left_pad="290"
name="close"
top_delta="0"
width="70" />
+-->
</layout_panel>
</layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_media_settings.xml b/indra/newview/skins/default/xui/en/floater_media_settings.xml
new file mode 100644
index 0000000000..6ba26f938d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_media_settings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater bottom="-666" can_close="true" can_drag_on_left="false" can_minimize="true"
+ can_resize="false" can_tear_off="true" default_tab_group="1" enabled="true"
+ width="365" height="535" left="330" min_height="430" min_width="620"
+ mouse_opaque="true" name="Medis Settings" title="Media Settings">
+ <button bottom="-525" enabled="true" follows="right|bottom" font="SansSerif"
+ halign="center" height="20" label="OK" label_selected="OK" left="75"
+ mouse_opaque="true" name="OK" scale_image="true" width="90" />
+ <button bottom_delta="0" enabled="true" follows="right|bottom" font="SansSerif"
+ halign="center" height="20" label="Cancel" label_selected="Cancel"
+ left_delta="93" mouse_opaque="true" name="Cancel" scale_image="true"
+ width="90" />
+ <button bottom_delta="0" enabled="true" follows="right|bottom" font="SansSerif"
+ halign="center" height="20" label="Apply" label_selected="Apply"
+ left_delta="93" mouse_opaque="true" name="Apply" scale_image="true"
+ width="90" />
+ <tab_container bottom="-500" enabled="true" follows="left|top|right|bottom" height="485"
+ left="0" mouse_opaque="false" name="tab_container" tab_group="1"
+ tab_position="top" tab_width="80" width="365" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml
index 30406cad63..aef5707fd4 100644
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -12,7 +12,7 @@
width="320"
min_width="320"
height="23"
- can_minimize="false"
+ can_minimize="true"
can_tear_off="false"
can_resize="false"
can_drag_on_left="false"
@@ -22,10 +22,10 @@
<flat_list_view
color="FloaterDefaultBackgroundColor"
follows="all"
- layout="topleft"
- name="notification_list"
- left="1"
+ layout="topleft"
+ name="notification_list"
+ left="1"
top="20"
- height="0"
- width="318"/>
+ height="0"
+ width="318"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index edbd28cd2d..053215f8ae 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -74,7 +74,11 @@
name="button focus"
picture_style="true"
tool_tip="Focus"
- width="20" />
+ width="20">
+ <button.commit_callback
+ function="BuildTool.setTool"
+ parameter="Focus" />
+ </button>
<button
follows="left|top"
height="20"
@@ -87,7 +91,11 @@
name="button move"
picture_style="true"
tool_tip="Move"
- width="20" />
+ width="20">
+ <button.commit_callback
+ function="BuildTool.setTool"
+ parameter="Move" />
+ </button>
<button
follows="left|top"
height="20"
@@ -100,7 +108,11 @@
name="button edit"
picture_style="true"
tool_tip="Edit"
- width="20" />
+ width="20">
+ <button.commit_callback
+ function="BuildTool.setTool"
+ parameter="Edit" />
+ </button>
<button
follows="left|top"
height="20"
@@ -113,7 +125,11 @@
name="button create"
picture_style="true"
tool_tip="Create"
- width="20" />
+ width="20">
+ <button.commit_callback
+ function="BuildTool.setTool"
+ parameter="Create" />
+ </button>
<button
follows="left|top"
height="20"
@@ -126,7 +142,11 @@
name="button land"
picture_style="true"
tool_tip="Land"
- width="20" />
+ width="20">
+ <button.commit_callback
+ function="BuildTool.setTool"
+ parameter="Land" />
+ </button>
<text
type="string"
text_color="LabelSelectedDisabledColor"
@@ -160,6 +180,8 @@
label="Pan (Ctrl-Shift)"
layout="topleft"
name="radio pan" />
+ <radio_group.commit_callback
+ function="BuildTool.commitRadioFocus"/>
</radio_group>
<slider_bar
follows="left|top"
@@ -171,7 +193,10 @@
top_delta="-2"
left_delta="100"
name="slider zoom"
- width="134" />
+ width="134">
+ <slider_bar.commit_callback
+ function="BuildTool.commitZoom"/>
+ </slider_bar>
<radio_group
left="10"
height="70"
@@ -193,6 +218,8 @@
label="Spin (Ctrl-Shift)"
layout="topleft"
name="radio spin" />
+ <radio_group.commit_callback
+ function="BuildTool.commitRadioMove"/>
</radio_group>
<radio_group
follows="left|top"
@@ -220,6 +247,8 @@
label="Select Texture"
layout="topleft"
name="radio select face" />
+ <radio_group.commit_callback
+ function="BuildTool.commitRadioEdit"/>
</radio_group>
<check_box
left="10"
@@ -227,7 +256,10 @@
control_name="EditLinkedParts"
label="Edit linked"
layout="topleft"
- name="checkbox edit linked parts" />
+ name="checkbox edit linked parts" >
+ <check_box.commit_callback
+ function="BuildTool.selectComponent"/>
+ </check_box>
<combo_box
height="19"
left="10"
@@ -248,6 +280,8 @@
label="Reference ruler"
name="Reference"
value="Reference" />
+ <combo_box.commit_callback
+ function="BuildTool.gridMode"/>
</combo_box>
<check_box
control_name="ScaleUniform"
@@ -286,7 +320,10 @@
name="Options..."
tool_tip="Set the Grid Options"
width="26"
- height="22" />
+ height="22" >
+ <button.commit_callback
+ function="BuildTool.gridOptions"/>
+ </button>
<button
follows="left|top"
height="20"
@@ -597,8 +634,9 @@
name="radio revert"
top_delta="15"
width="114" />
+ <radio_group.commit_callback
+ function="BuildTool.commitRadioLand"/>
</radio_group>
-
<text
type="string"
length="1"
@@ -624,6 +662,7 @@
Size
</text>
<slider_bar
+ control_name ="LandBrushSize"
follows="left|top"
height="19"
initial_value="2.0"
@@ -656,7 +695,10 @@
min_val="-1"
name="slider force"
top_delta="-3"
- width="80" />
+ width="80" >
+ <slider_bar.commit_callback
+ function="BuildTool.LandBrushForce"/>
+ </slider_bar>
<button
follows="left|top"
font="SansSerifSmall"
@@ -668,7 +710,10 @@
left="135"
name="button apply to selection"
tool_tip="Modify Selected Land"
- width="78" />
+ width="78">
+ <button.commit_callback
+ function="BuildTool.applyToSelection"/>
+ </button>
<text
type="string"
text_color="LabelSelectedDisabledColor"
@@ -2215,7 +2260,7 @@
left="10"
name="texture control"
tool_tip="Click to choose a picture"
- top="10"
+ top="8"
width="64" />
<color_swatch
border_color="0.45098 0.517647 0.607843 1"
@@ -2237,7 +2282,7 @@
layout="topleft"
left_pad="20"
name="color trans"
- top="10"
+ top="6"
width="100">
Transparency %
</text>
@@ -2261,7 +2306,7 @@
layout="topleft"
left_delta="0"
name="glow label"
- top_pad="4"
+ top_pad="2"
width="80">
Glow
</text>
@@ -2281,7 +2326,7 @@
layout="topleft"
left_delta="0"
name="checkbox fullbright"
- top_pad="7"
+ top_pad="4"
width="81" />
<text
type="string"
@@ -2291,7 +2336,7 @@
layout="topleft"
left="10"
name="tex gen"
- top_pad="10"
+ top_pad="5"
width="87">
Mapping
</text>
@@ -2439,6 +2484,40 @@
name="weave"
value="weave" />
</combo_box>
+ <!--
+ <line_editor
+ bevel_style="in"
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ max_length="63"
+ name="Home Url"
+ select_on_focus="true"
+ top="134"
+ width="250" />
+ <check_box
+ height="16"
+ label="Media Face"
+ layout="topleft"
+ left_delta="0"
+ name="has media"
+ top_pad="6"
+ width="70" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="20"
+ label="Set Media Info"
+ label_selected="Set Media Info"
+ layout="topleft"
+ left_pad="60"
+ name="media info set"
+ top_delta="-4"
+ width="120" />
+-->
<text
type="string"
length="1"
@@ -2447,7 +2526,7 @@
layout="topleft"
left="10"
name="tex scale"
- top_pad="15"
+ top_pad="5"
width="200">
Repeats per Face
</text>
@@ -2461,7 +2540,7 @@
left="20"
max_val="100"
name="TexScaleU"
- top_pad="10"
+ top_pad="6"
width="160" />
<check_box
height="19"
@@ -2469,7 +2548,7 @@
layout="topleft"
left_pad="10"
name="checkbox flip s"
- top_delta="1"
+ top_delta="0"
width="70" />
<spinner
follows="left|top"
@@ -2489,61 +2568,43 @@
layout="topleft"
left_pad="10"
name="checkbox flip t"
- top_delta="1"
+ top_delta="0"
width="70" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="tex rotate"
- top_pad="20"
- width="102">
- Rotation (degrees)
- </text>
+
<spinner
decimal_digits="2"
follows="left|top"
height="19"
increment="1"
initial_value="0"
+ label="Rotation (degrees)"
layout="topleft"
- left_delta="102"
+ label_width="100"
+ left="10"
max_val="9999"
min_val="-9999"
name="TexRot"
- top_delta="0"
- width="68" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="rpt"
- top_pad="0"
- width="160">
- Repeats Per Meter
- </text>
+ top_delta="25"
+ width="170" />
+
<spinner
decimal_digits="1"
follows="left|top"
height="19"
initial_value="1"
+ label="Repeats Per Meter"
layout="topleft"
- left_delta="102"
+ label_width="100"
+ left="10"
max_val="10"
min_val="0.1"
name="rptctrl"
- top_delta="0"
- width="68" />
+ top_delta="20"
+ width="170" />
<button
follows="left|top"
font="SansSerifSmall"
- height="22"
+ height="18"
label="Apply"
label_selected="Apply"
layout="topleft"
@@ -2558,7 +2619,7 @@
layout="topleft"
left="10"
name="tex offset"
- top_pad="20"
+ top_delta="20"
width="200">
Texture Offset
</text>
@@ -2572,7 +2633,7 @@
left="20"
min_val="-1"
name="TexOffsetU"
- top_pad="10"
+ top_pad="5"
width="160" />
<spinner
follows="left|top"
@@ -2584,10 +2645,9 @@
left_delta="0"
min_val="-1"
name="TexOffsetV"
- top_pad="2"
+ top_pad="1"
width="160" />
-<!--TODO: KILL THIS-->
- <!-- <text
+ <text
type="string"
length="1"
follows="left|top"
@@ -2595,7 +2655,7 @@
layout="topleft"
left="10"
name="textbox autofix"
- top="332"
+ top_pad="4"
width="160">
Align media texture
(must load first)
@@ -2607,10 +2667,75 @@
label="Align"
label_selected="Align"
layout="topleft"
- left="112"
+ left="122"
name="button align"
- top="340"
- width="68" />-->
+ top_pad="-19"
+ width="68" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="10"
+ top_pad="0"
+ name="media_tex"
+ width="100">
+ Media:
+ </text>
+ <line_editor
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left="20"
+ max_length="63"
+ name="media_info"
+ select_on_focus="true"
+ top_delta="12"
+ width="230" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="13"
+ width="13"
+ image_unselected="add_btn.tga"
+ label=""
+ layout="topleft"
+ left="20"
+ name="add_media"
+ top_pad="3">
+ <button.commit_callback
+ function="BuildTool.AddMedia"/>
+ </button>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="13"
+ width="13"
+ image_unselected="del_btn.tga"
+ label=""
+ layout="topleft"
+ left_pad="10"
+ name="delete_media"
+ top_delta="0"
+ left_delta="10" >
+ <button.commit_callback
+ function="BuildTool.DeleteMedia"/>
+ </button>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="15"
+ width="15"
+ image_unselected="gear.tga"
+ label=""
+ layout="topleft"
+ name="edit_media"
+ top_delta="0"
+ left_delta="190">
+ <button.commit_callback
+ function="BuildTool.EditMedia"/>
+ </button>
</panel>
<panel
border="false"
@@ -2642,13 +2767,13 @@
width="130" />
<panel_inventory
follows="left|top"
- height="310"
+ height="210"
layout="topleft"
left="10"
name="contents_inventory"
top="50"
width="260" />
- </panel>
+ </panel>
</tab_container>
<panel
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml
new file mode 100644
index 0000000000..0eb2c5e1be
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="108"
+ layout="topleft"
+ name="whitelist_entry"
+ width="390">
+
+ <text type="string" length="1" bottom="20" follows="top|left" height="15" layout="topleft"
+ left="10" name="media_label" top="20">
+ Enter a URL or URL pattern to add to the list of allowed domains
+ </text>
+
+ <line_editor bottom_delta="40" enabled="true" follows="left|top" font="SansSerif"
+ height="20" left="10" name="whitelist_entry"
+ tool_tip="Enter a URL or URL pattern to White List"
+ width="350" />
+
+ <button follows="top|left" height="20" font="SansSerifSmall" label="OK"
+ layout="topleft" left="10" name="ok_btn" bottom_delta="28" width="64" />
+
+ <button follows="top|left" height="20" font="SansSerifSmall" label="Cancel"
+ layout="topleft" left_pad="5" name="cancel_btn" bottom_delta="0" width="64" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
new file mode 100644
index 0000000000..d9cba27b88
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Teleport History Item Context Menu">
+ <menu_item_call
+ label="Teleport"
+ layout="topleft"
+ name="Teleport">
+ <menu_item_call.on_click
+ function="TeleportHistory.Teleport" />
+ </menu_item_call>
+ <menu_item_call
+ label="More Information"
+ layout="topleft"
+ name="More Information">
+ <menu_item_call.on_click
+ function="TeleportHistory.MoreInformation" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="Copy">
+ <menu_item_call.on_click
+ function="TeleportHistory.Copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Make Landmark"
+ layout="topleft"
+ name="Make Landmark">
+ <menu_item_call.on_click
+ function="TeleportHistory.MakeLandmark" />
+ </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml
new file mode 100644
index 0000000000..ecc1d8a954
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Teleport History Item Context Menu">
+ <menu_item_call
+ label="Open"
+ layout="topleft"
+ name="TabOpen">
+ <menu_item_call.on_click
+ function="TeleportHistory.TabOpen" />
+ </menu_item_call>
+ <menu_item_call
+ label="Close"
+ layout="topleft"
+ name="TabClose">
+ <menu_item_call.on_click
+ function="TeleportHistory.TabClose" />
+ </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 10aa23b715..2c77f61da6 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -128,13 +128,13 @@
function="World.SetAway" />
</menu_item_call>
<menu_item_separator
- layout="topleft"/>
+ layout="topleft"/>
<menu_item_call
label="Set Busy"
layout="topleft"
name="Set Busy">
<menu_item_call.on_click
- function="World.SetBusy"/>
+ function="World.SetBusy"/>
</menu_item_call>
</menu>
<menu_item_separator
@@ -1042,15 +1042,6 @@
<menu_item_separator
layout="topleft" />
<menu_item_call
- label="Report Bug..."
- layout="topleft"
- name="ReportBug">
- <menu_item_call.on_click
- function="PromptShowURL"
- name="ReportBug_url"
- parameter="hud,http://help.secondlife.com/en/bugreport/" />
- </menu_item_call>
- <menu_item_call
label="Report Abuse..."
layout="topleft"
name="Report Abuse">
@@ -2771,15 +2762,6 @@
function="Advanced.ShowDebugSettings"
parameter="skin" />
</menu_item_call>
- <menu_item_check
- label="Editable UI"
- layout="topleft"
- name="Editable UI">
- <menu_item_check.on_check
- function="Advanced.CheckEditableUI" />
- <menu_item_check.on_click
- function="Advanced.ToggleEditableUI" />
- </menu_item_check>
<menu_item_call
label="Dump SelectMgr"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 044194a4ed..fe088b43be 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -646,6 +646,19 @@ This entire region is damage enabled.
Scripts must be allowed to run for weapons to work.
</notification>
+<notification
+ icon="alertmodal.tga"
+ name="MultipleFacesSelected"
+ type="alertmodal">
+ Multiple faces are currently selected.
+If you continue this action, separate instances of media will be set on multiple faces of the object.
+To place the media on only one face, choose Select Texture and click on the desired face of that object then click Add.
+ <usetemplate
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
<notification
icon="alertmodal.tga"
name="MustBeInParcel"
@@ -783,6 +796,20 @@ There is no reimbursement for fees paid.
yestext="OK"/>
</notification>
+
+<notification
+ icon="alertmodal.tga"
+ name="DeleteMedia"
+ type="alertmodal">
+You have selected to delete the media associated with this face.
+Are you sure you want to continue?
+ <usetemplate
+ ignoretext="Confirm before I delete media from an object"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
<notification
icon="alertmodal.tga"
name="ClassifiedSave"
@@ -1215,7 +1242,7 @@ Please move all objects to be acquired onto the same region.
type="alertmodal">
[EXTRA]
-Go to [_URL] for information on purchasing currency?
+Go to [_URL] for information on purchasing L$?
<url option="0" name="url">
http://secondlife.com/app/currency/
@@ -1691,7 +1718,6 @@ No Group selected.
type="alertmodal">
Unable to deed land:
Cannot find the region this land is in.
-Please use Help &gt; Report Bug to report this.
</notification>
<notification
@@ -1772,8 +1798,6 @@ Parcels you own appear in green.
type="alertmodal">
Unable to abandon land:
Cannot find the region this land is in.
-
-Please use Help &gt; Report Bug to report this.
</notification>
<notification
@@ -1846,8 +1870,6 @@ Divide land?
type="alertmodal">
Unable to divide land:
Cannot find the region this land is in.
-
-Please use Help &gt; Report Bug to report this.
</notification>
<notification
@@ -1856,8 +1878,6 @@ Please use Help &gt; Report Bug to report this.
type="alertmodal">
Unable to join land:
Cannot find the region this land is in.
-
-Please use Help &gt; Report Bug to report this.
</notification>
<notification
@@ -1973,8 +1993,6 @@ Unable to save &apos;[NAME]&apos; to wearable file. You will need to free up so
type="alertmodal">
Unable to save [NAME] to central asset store.
This is usually a temporary failure. Please customize and save the wearable again in a few minutes.
-
-If this problem persists, please click on Help &gt; Report Bug and provide details about your network setup.
</notification>
<notification
@@ -2758,18 +2776,6 @@ Go to secondlife.com to manage your account?
<notification
icon="alertmodal.tga"
- name="WebLaunchBugReport101"
- type="alertmodal">
-Visit the [SECOND_LIFE] Wiki and learn how to report bugs correctly.
- <usetemplate
- ignoretext="Launch my browser to learn how to report a Bug"
- name="okcancelignore"
- notext="Cancel"
- yestext="OK"/>
- </notification>
-
- <notification
- icon="alertmodal.tga"
name="WebLaunchSecurityIssues"
type="alertmodal">
Visit the [SECOND_LIFE] Wiki for details of how to report a security issue.
@@ -4275,22 +4281,6 @@ The resolution of this report applies only to this Region. Residents&apos; acces
<notification
icon="alertmodal.tga"
- name="HelpReportBug"
- type="alertmodal">
-Use this tool to *only* report technical features that do not perform as described or expected, please provide as much detail as possible.
-You may reply to the auto-response email to add more details to your report.
-
-All bug reports are investigated and assessed. No email response will be sent.
-
-If you are having a technical difficulty, please contact Support at:
-
-http://secondlife.com/community/support.php
-
-Note: Incomplete reports will not be investigated
- </notification>
-
- <notification
- icon="alertmodal.tga"
name="HelpReportAbuseSelectCategory"
type="alertmodal">
Please select a category for this abuse report.
@@ -4299,14 +4289,6 @@ Selecting a category helps us file and process abuse reports.
<notification
icon="alertmodal.tga"
- name="HelpReportBugSelectCategory"
- type="alertmodal">
-Please select a category for this bug.
-Selecting a category helps us file and process bug reports.
- </notification>
-
- <notification
- icon="alertmodal.tga"
name="HelpReportAbuseAbuserNameEmpty"
type="alertmodal">
Please enter the name of the abuser.
@@ -4331,14 +4313,6 @@ Entering an accurate summary helps us file and process abuse reports.
<notification
icon="alertmodal.tga"
- name="HelpReportBugSummaryEmpty"
- type="alertmodal">
-Please enter a summary of the bug.
-Entering an accurate summary helps us file and process bug reports.
- </notification>
-
- <notification
- icon="alertmodal.tga"
name="HelpReportAbuseDetailsEmpty"
type="alertmodal">
Please enter a detailed description of the abuse that took place.
@@ -4348,15 +4322,6 @@ Entering an accurate description helps us file and process abuse reports.
<notification
icon="alertmodal.tga"
- name="HelpReportBugDetailsEmpty"
- type="alertmodal">
-Please enter a detailed description of the bug.
-Be as specific as you can, including steps to reproduce the bug if possible.
-Entering an accurate description helps us file and process bug reports.
- </notification>
-
- <notification
- icon="alertmodal.tga"
name="HelpReportAbuseContainsCopyright"
type="alertmodal">
Dear Resident,
@@ -6547,6 +6512,17 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block
Unable to find the help topic for this element.
</notification>
+ <notification
+ icon="alertmodal.tga"
+ name="ObjectMediaFailure"
+ type="alertmodal">
+Server Error: Media update or get failed.
+&apos;[ERROR]&apos;
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
<global name="UnsupportedCPU">
- Your CPU speed does not meet the minimum requirements.
</global>
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 90b331a39f..cd7e340ff1 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -79,7 +79,6 @@
label="Move"
layout="topleft"
name="movement_btn"
- tab_stop="false"
tool_tip="Shows/Hide Movement controls"
top="6"
width="70">
@@ -117,7 +116,6 @@
label="View"
layout="topleft"
left="0"
- tab_stop="false"
tool_tip="Shows/Hide Camera controls"
top="6"
name="camera_btn"
@@ -133,7 +131,6 @@
height="20"
width="20"
left_pad="0"
- tab_stop="false"
is_toggle="true"
picture_style="true"
image_selected="toggle_button_selected"
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index c4c8aa24c4..fb4ce436e8 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -28,7 +28,7 @@
width="25"
height="25"
label=""
- follows="top|left"
+ follows="top|right"
image_overlay="BackArrow_Off"
tab_stop="false" />
<text
@@ -41,6 +41,7 @@
text_color="white"
follows="top|left|right"
mouse_opaque="true"
+ use_ellipses="true"
name="group_name">(Loading...)</text>
<line_editor
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index e7fb3fa208..c96c296057 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -26,9 +26,8 @@
layout="topleft"
left="0"
name="login_html"
- hide_loading="true"
right="-1"
- start_url="data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody bgcolor=%22#000000%22 text=%22ffffff%22%3E%3Ch1%3E%3Ctt%3Eloading...%3C/tt%3E%3C/h1%3E %3C/body%3E %3C/html%3E"
+ start_url=""
top="1" />
<text
type="string"
@@ -52,7 +51,7 @@
max_length="31"
name="first_name_edit"
select_on_focus="true"
- tool_tip="Second Life First Name"
+ tool_tip="[SECOND_LIFE] First Name"
top_pad="2"
width="120" />
<text
@@ -78,6 +77,7 @@
max_length="31"
name="last_name_edit"
select_on_focus="true"
+ tool_tip="[SECOND_LIFE] Last Name"
top_pad="2"
width="120" />
<text
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
new file mode 100644
index 0000000000..b66aad1853
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ enabled="true"
+ follows="left|top|right|bottom"
+ height="500"
+ label="General"
+ left="102"
+ mouse_opaque="true"
+ name="Media Settings General"
+ width="365">
+
+ <text
+ bottom_delta="-17"
+ follows="top|left"
+ height="15"
+ left="10"
+ name="">
+ Home URL:
+ </text>
+ <line_editor
+ bottom_delta="-21"
+ enabled="true"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ left="10"
+ name="home_url"
+ tool_tip="The home URL for this media source"
+ width="340">
+ <!-- <line_editor.commit_callback
+ function="Media.CommitHomeURL"/> -->
+ </line_editor>
+ <text
+ bottom_delta="-20"
+ follows="top|left"
+ height="15"
+ left="10"
+ name="current_url_label">
+ Current URL:
+ </text>
+ <line_editor
+ bottom_delta="-20"
+ enabled="false"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ left="10"
+ name="current_url"
+ tool_tip="The current URL for this media source"
+ value=""
+ width="340" />
+ <button
+ bottom_delta="-20"
+ follows="top|left"
+ height="20"
+ label="Reset"
+ left_delta="233"
+ name="current_url_reset_btn"
+ width="110" >
+ <button.commit_callback
+ function="Media.ResetCurrentUrl"/>
+ </button>
+
+ <web_browser
+ border_visible="false"
+ bottom_delta="-120"
+ follows="top|left"
+ left="120"
+ name="preview_media"
+ width="128"
+ height="128"
+ start_url="about:blank"
+ decouple_texture_size="true" />
+
+ <text
+ bottom_delta="-15"
+ follows="top|left"
+ height="15"
+ left="164"
+ name="">
+ Preview
+ </text>
+
+ <text
+ bottom_delta="-20"
+ follows="top|left"
+ height="15"
+ left="10"
+ name="">
+ Controls:
+ </text>
+ <combo_box
+ allow_text_entry="false"
+ bottom_delta="-20"
+ enabled="true"
+ follows="left|top"
+ height="18"
+ left="10"
+ max_chars="20"
+ mouse_opaque="true"
+ name="controls"
+ width="120">
+ <combo_item
+ type="string"
+ length="1"
+ enabled="true"
+ name="Standard"
+ value="Standard">
+ Standard
+ </combo_item>
+ <combo_item
+ type="string"
+ length="1"
+ enabled="true"
+ name="Mini"
+ value="Mini">
+ Mini
+ </combo_item>
+ </combo_box>
+
+ <check_box
+ bottom_delta="-25"
+ enabled="true"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="false"
+ label="Auto Loop"
+ left="10"
+ mouse_opaque="true"
+ name="auto_loop"
+ radio_style="false"
+ width="150" />
+
+ <check_box
+ bottom_delta="-25"
+ enabled="true"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="false"
+ label="First Click Interacts"
+ left_delta="0"
+ mouse_opaque="true"
+ name="first_click_interact"
+ radio_style="false"
+ width="150" />
+
+ <check_box
+ bottom_delta="-25"
+ enabled="true"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="false"
+ label="Auto Zoom"
+ left_delta="0"
+ mouse_opaque="true"
+ name="auto_zoom"
+ radio_style="false"
+ width="150" />
+
+ <check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall"
+ height="16" initial_value="false"
+ label="Use Default Alternative Image" left="10" mouse_opaque="true"
+ name="alt_image_enable" radio_style="false" width="150" />
+
+ <check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall"
+ height="16" initial_value="false"
+ label="Auto Play Media" left="10" mouse_opaque="true"
+ name="auto_play" radio_style="false" width="150" />
+ <text bottom_delta="-14" follows="top|left" height="15" left="30" width="340"
+ enabled="false" name="">
+ Note: Parcel Owners &amp; Residents can override this setting
+ </text>
+
+ <check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall"
+ height="16" initial_value="false"
+ label="Auto Scale Media on Face of Object" left="10" mouse_opaque="true"
+ name="auto_scale" radio_style="false" width="150" />
+ <text bottom_delta="-20" follows="top|left" height="15" left="30" name="">
+ Size:
+ </text>
+ <spinner bottom_delta="0"
+ decimal_digits="0" enabled="true" follows="left|top" height="16"
+ increment="1" initial_val="256" label="" label_width="0"
+ left_delta="40" max_val="2000" min_val="0" mouse_opaque="true"
+ name="width_pixels" width="50" />
+ <text bottom_delta="0" follows="top|left" height="15" left_delta="60" name="">
+ X
+ </text>
+ <spinner bottom_delta="0"
+ decimal_digits="0" enabled="true" follows="left|top" height="16"
+ increment="1" initial_val="256" label="" label_width="0"
+ left_delta="20" max_val="2000" min_val="0" mouse_opaque="true"
+ name="height_pixels" width="50" />
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml
new file mode 100644
index 0000000000..f11364874a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel border="true" enabled="true" follows="left|top|right|bottom"
+ height="500" label="Controls" left="102" mouse_opaque="true"
+ name="Media settings for controls" width="365">
+
+ <text bottom_delta="-50" follows="top|left" height="15" left="10" name="" enabled="false">
+ Owner
+ </text>
+ <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+ height="16" initial_value="false"
+ label="Disable Navigation &amp; Interactivity" left="30" mouse_opaque="true"
+ name="perms_owner_interact" radio_style="false" width="250" />
+
+ <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+ height="16" initial_value="false"
+ label="Hide Control Bar" left="30" mouse_opaque="true"
+ name="perms_owner_control" radio_style="false" width="250" />
+
+ <text bottom_delta="-36" follows="top|left" height="15" left="10" name="perms_group_name_label" enabled="false">
+ Group
+ </text>
+ <name_box bottom_delta="-5" enabled="false" follows="left|top" font="SansSerif"
+ height="20" left="60" name="perms_group_name"
+ value =""
+ width="200" />
+ <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+ height="16" initial_value="false"
+ label="Disable Navigation &amp; Interactivity" left="30" mouse_opaque="true"
+ name="perms_group_interact" radio_style="false" width="250" />
+
+ <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+ height="16" initial_value="false"
+ label="Hide Control Bar" left="30" mouse_opaque="true"
+ name="perms_group_control" radio_style="false" width="250" />
+
+ <text bottom_delta="-36" follows="top|left" height="15" left="10" name="" enabled="false">
+ Anyone
+ </text>
+ <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+ height="16" initial_value="false"
+ label="Disable Navigation &amp; Interactivity" left="30" mouse_opaque="true"
+ name="perms_anyone_interact" radio_style="false" width="250" />
+
+ <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+ height="16" initial_value="false"
+ label="Hide Control Bar" left="30" mouse_opaque="true"
+ name="perms_anyone_control" radio_style="false" width="250" />
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_security.xml b/indra/newview/skins/default/xui/en/panel_media_settings_security.xml
new file mode 100644
index 0000000000..695e956e41
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_security.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ enabled="true"
+ follows="left|top|right|bottom"
+ height="500"
+ label="Security"
+ left="102"
+ mouse_opaque="true"
+ name="Media Settings Security"
+ width="365">
+ <check_box
+ bottom_delta="-40"
+ enabled="true"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="false"
+ label="Only Allow Access to Specified URLs (by prefix)"
+ left="10"
+ mouse_opaque="true"
+ name="whitelist_enable"
+ radio_style="false"
+ width="250" />
+ <scroll_list
+ follows="top|left"
+ height="200"
+ left="30"
+ name="whitelist"
+ width="315"
+ enabled="true" />
+ <button
+ bottom_delta="-30"
+ follows="top|left"
+ height="20"
+ label="Add"
+ left="30"
+ name="whitelist_add"
+ width="70"
+ enabled="true">
+ <button.commit_callback
+ function="Media.whitelistAdd"/>
+ </button>
+ <button
+ bottom_delta="0"
+ follows="top|left"
+ height="20"
+ label="Delete"
+ left="275"
+ name="whitelist_del"
+ width="70"
+ enabled="true">
+ <button.commit_callback
+ function="Media.whitelistDelete"/>
+ </button>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 683a54b366..4088d96ebf 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -35,6 +35,8 @@
follows="right"
height="20"
speak_button.font="SansSerifMedium"
+ speak_button.tab_stop="true"
+ show_button.tab_stop="true"
layout="topleft"
left_pad="5"
name="talk"
diff --git a/indra/newview/skins/default/xui/en/panel_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml
index 58ebac2a84..2056ec14d5 100644
--- a/indra/newview/skins/default/xui/en/panel_notes.xml
+++ b/indra/newview/skins/default/xui/en/panel_notes.xml
@@ -2,7 +2,7 @@
<panel
bevel_style="in"
follows="left|top|right|bottom"
- height="420"
+ height="460"
label="Notes &amp; Privacy"
layout="topleft"
left="0"
@@ -16,7 +16,7 @@
layout="topleft"
left="0"
top="0"
- height="420"
+ height="430"
width="313"
border_size="0">
<panel
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index d0bde77cf2..1bd1953397 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="left|top|right|bottom"
- height="515"
+ height="555"
label="Picks"
layout="topleft"
left="0"
@@ -11,7 +11,7 @@
<flat_list_view
color="DkGray2"
follows="left|top|right|bottom"
- height="495"
+ height="465"
layout="topleft"
left="0"
name="picks_list"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 8f710545d5..06ecfdc995 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -261,17 +261,17 @@ My Avatar:
label="Show script errors"
layout="topleft"
left="30"
- name="first_person_avatar_visible"
+ name="show_script_errors"
width="256"
top_pad="10"/>
<radio_group
- enabled_control="EnableVoiceChat"
- control_name="VoiceEarLocation"
+ enabled_control="EnableShowScriptErrors"
+ control_name="ShowScriptErrorsLocation"
draw_border="false"
height="40"
layout="topleft"
left_delta="50"
- name="ear_location"
+ name="show_location"
top_pad="5"
width="364">
<radio_item
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index 56ba5970f2..02d179d503 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="all"
- height="515"
+ height="560"
label="Profile"
layout="topleft"
left="0"
@@ -25,7 +25,7 @@
<scroll_container
color="DkGray2"
follows="left|top|right|bottom"
- height="515"
+ height="500"
min_height="300"
layout="topleft"
name="profile_scroll"
@@ -265,6 +265,7 @@
left="0"
name="profile_buttons_panel"
top_pad="0"
+ height="25"
width="313">
<button
follows="bottom|left"
@@ -316,6 +317,7 @@
name="profile_me_buttons_panel"
top_pad="0"
visible="false"
+ height="25"
width="313">
<button
follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml
index cbe646f3cc..606535115d 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml
@@ -2,7 +2,7 @@
<panel
background_visible="true"
follows="all"
- height="660"
+ height="570"
layout="topleft"
min_height="350"
min_width="240"
@@ -50,7 +50,7 @@
width="25" />
<tab_container
follows="left|top|right|bottom"
- height="660"
+ height="560"
layout="topleft"
left="10"
name="tabs"
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index 5738879c5a..a3c714ce72 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -184,9 +184,9 @@
layout="topleft"
name="Help..." />
<menu_item_call
- label="LSL Wiki Help..."
+ label="Keyword Help..."
layout="topleft"
- name="LSL Wiki Help..." />
+ name="Keyword Help..." />
</menu>
</menu_bar>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
index f25c4bfbba..aa76a61c15 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
@@ -19,4 +19,17 @@
top="4"
value="Side Panel"
width="255" />
+ <button
+ follows="left|right|top"
+ font="SansSerif"
+ height="23"
+ label="?"
+ layout="topleft"
+ name="show_help"
+ top="5"
+ right="-8"
+ width="28">
+ <button.commit_callback
+ function="Button.ShowHelp" />
+ </button>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index c178554287..f6ffd2e4ee 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -52,7 +52,7 @@
left="-210"
name="buycurrency"
picture_style="true"
- tool_tip="My Balance / Buy currency"
+ tool_tip="My Balance / Buy L$"
top="0"
width="117" />
<text
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
index a0fc986423..aa95a2baef 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -111,7 +111,7 @@
width="380">
</flat_list_view>
</accordion_tab>
-
+
<accordion_tab
can_resize="false"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 13a53a4ce3..1e85cac539 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -93,7 +93,6 @@
<string name="BUTTON_RESTORE">Restore</string>
<string name="BUTTON_MINIMIZE">Minimize</string>
<string name="BUTTON_TEAR_OFF">Tear Off</string>
- <string name="BUTTON_EDIT">Edit</string>
<string name="BUTTON_DOCK">Dock</string>
<string name="BUTTON_UNDOCK">Undock</string>
<string name="BUTTON_HELP">Show Help</string>
@@ -308,112 +307,115 @@ Sleeps script for [SLEEP_TIME] seconds.
<string name="LSLTipText_llSin">
float llSin(float theta)
-theta in radians
+Returns the sine of theta (theta in radians)
</string>
<string name="LSLTipText_llCos">
float llCos(float theta)
-theta in radians
+Returns the cosine of theta (theta in radians)
</string>
<string name="LSLTipText_llTan">
float llTan(float theta)
-theta radians
+Returns the tangent of theta (theta in radians)
</string>
<string name="LSLTipText_llAtan2">
float llAtan2(float y, float x)
+Returns the arctangent2 of y, x
</string>
<string name="LSLTipText_llSqrt">
float llSqrt(float val)
-returns 0 and triggers a Math Error for imaginary results
+Returns the square root of val, or returns 0 and triggers a Math Error for imaginary results
</string>
<string name="LSLTipText_llPow">
float llPow(float base, float exponent)
-returns 0 and triggers Math Error for imaginary results
+Returns the base raised to the power exponent, or returns 0 and triggers Math Error for imaginary results
</string>
<string name="LSLTipText_llAbs">
integer llAbs(integer val)
+Returns the positive version of val
</string>
<string name="LSLTipText_llFabs">
float llFabs(float val)
+Returns the positive version of val
</string>
<string name="LSLTipText_llFrand">
float llFrand(float mag)
-returns random number in range [0,mag)
+Returns a pseudo random number in the range [0,mag) or (mag,0]
</string>
<string name="LSLTipText_llFloor">
integer llFloor(float val)
-returns largest integer value &lt;= val
+Returns largest integer value &lt;= val
</string>
<string name="LSLTipText_llCeil">
integer llCeil(float val)
-returns smallest integer value &gt;= val
+Returns smallest integer value &gt;= val
</string>
<string name="LSLTipText_llRound">
integer llRound(float val)
-returns val rounded to the nearest integer
+Returns val rounded to the nearest integer
</string>
<string name="LSLTipText_llVecMag">
float llVecMag(vector v)
-returns the magnitude of v
+Returns the magnitude of v
</string>
<string name="LSLTipText_llVecNorm">
vector llVecNorm(vector v)
-returns the v normalized
+Returns the v normalized
</string>
<string name="LSLTipText_llVecDist">
float llVecDist(vector v1, vector v2)
-returns the 3D distance between v1 and v2
+Returns the 3D distance between v1 and v2
</string>
<string name="LSLTipText_llRot2Euler">
vector llRot2Euler(rotation q)
-returns the Euler representation (roll, pitch, yaw) of q
+Returns the Euler representation (roll, pitch, yaw) of q
</string>
<string name="LSLTipText_llEuler2Rot">
rotation llEuler2Rot(vector v)
-returns the rotation representation of Euler Angles v
+Returns the rotation representation of Euler Angles v
</string>
<string name="LSLTipText_llAxes2Rot">
rotation llAxes2Rot(vector fwd, vector left, vector up)
-returns the rotation defined by the coordinate axes
+Returns the rotation defined by the coordinate axes
</string>
<string name="LSLTipText_llRot2Fwd">
vector llRot2Fwd(rotation q)
-returns the forward vector defined by q
+Returns the forward vector defined by q
</string>
<string name="LSLTipText_llRot2Left">
vector llRot2Left(rotation q)
-returns the left vector defined by q
+Returns the left vector defined by q
</string>
<string name="LSLTipText_llRot2Up">
vector llRot2Up(rotation q)
-returns the up vector defined by q
+Returns the up vector defined by q
</string>
<string name="LSLTipText_llRotBetween">
rotation llRotBetween(vector v1, vector v2)
-returns the rotation to rotate v1 to v2
+Returns the rotation to rotate v1 to v2
</string>
<string name="LSLTipText_llWhisper">
llWhisper(integer channel, string msg)
-whispers msg on channel
+Whispers the text of msg on channel
</string>
<string name="LSLTipText_llSay">
llSay(integer channel, string msg)
-says msg on channel
+Says the text of msg on channel
</string>
<string name="LSLTipText_llShout">
llShout(integer channel, string msg)
-shouts msg on channel
+Shouts the text of msg on channel
</string>
<string name="LSLTipText_llListen">
integer llListen(integer channel, string name, key id, string msg)
-sets a callback for msg on channel from name and id (name, id, and/or msg can be empty) and returns an identifier that can be used to deactivate or remove the listen
+Sets a callback for msg on channel from name and id (name, id, and/or msg can be empty) and returns an identifier that can be used to deactivate or remove the listen
</string>
<string name="LSLTipText_llListenControl">
llListenControl(integer number, integer active)
-makes a listen event callback active or inactive
+Makes a listen event callback active or inactive
</string>
<string name="LSLTipText_llListenRemove">
llListenRemove(integer number)
-removes listen event callback number
+Removes listen event callback number
</string>
<string name="LSLTipText_llSensor">
llSensor(string name, key id, integer type, float range, float arc)
@@ -421,43 +423,43 @@ Performs a single scan for name and id with type (AGENT, ACTIVE, PASSIVE, and/or
</string>
<string name="LSLTipText_llSensorRepeat">
llSensorRepeat(string name, key id, integer type, float range, float arc, float rate)
-sets a callback for name and id with type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within range meters and arc radians of forward vector (name, id, and/or keytype can be empty or 0) and repeats every rate seconds
+Sets a callback for name and id with type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within range meters and arc radians of forward vector (name, id, and/or keytype can be empty or 0) and repeats every rate seconds
</string>
<string name="LSLTipText_llSensorRemove">
llSensorRemove()
-removes sensor
+Removes the sensor setup by llSensorRepeat
</string>
<string name="LSLTipText_llDetectedName">
string llDetectedName(integer number)
-returns the name of detected object number (returns empty string if number is not valid sensed object)
+Returns the name of detected object number (returns empty string if number is not a valid sensed object)
</string>
<string name="LSLTipText_llDetectedKey">
key llDetectedKey(integer number)
-returns the key of detected object number (returns empty key if number is not valid sensed object)
+Returns the key of detected object number (returns empty key if number is not a valid sensed object)
</string>
<string name="LSLTipText_llDetectedOwner">
key llDetectedOwner(integer number)
-returns the key of detected object&apos;s owner (returns empty key if number is not valid sensed object)
+Returns the key of detected object&apos;s owner (returns empty key if number is not a valid sensed object)
</string>
<string name="LSLTipText_llDetectedType">
integer llDetectedType(integer number)
-returns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object (returns 0 if number is not valid sensed object)
+Returns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object (returns 0 if number is not a valid sensed object)
</string>
<string name="LSLTipText_llDetectedPos">
vector llDetectedPos(integer number)
-returns the position of detected object number (returns &lt;0,0,0&gt; if number is not valid sensed object)
+Returns the position of detected object number (returns &lt;0,0,0&gt; if number is not a valid sensed object)
</string>
<string name="LSLTipText_llDetectedVel">
vector llDetectedVel(integer number)
-returns the velocity of detected object number (returns &lt;0,0,0&gt; if number is not valid sensed object)
+Returns the velocity of detected object number (returns &lt;0,0,0&gt; if number is not a valid sensed object)
</string>
<string name="LSLTipText_llDetectedGrab">
vector llDetectedGrab(integer number)
-returns the grab offset of the user touching object (returns &lt;0,0,0&gt; if number is not valid sensed object)
+Returns the grab offset of the user touching object (returns &lt;0,0,0&gt; if number is not a valid sensed object)
</string>
<string name="LSLTipText_llDetectedRot">
rotation llDetectedRot(integer number)
-returns the rotation of detected object number (returns &lt;0,0,0,1&gt; if number is not valid sensed object)
+Returns the rotation of detected object number (returns &lt;0,0,0,1&gt; if number is not a valid sensed object)
</string>
<string name="LSLTipText_llDetectedGroup">
integer llDetectedGroup(integer number)
@@ -465,127 +467,127 @@ Returns TRUE if detected object is part of same group as owner
</string>
<string name="LSLTipText_llDetectedLinkNumber">
integer llDetectedLinkNumber(integer number)
-returns the link position of the triggered event for touches and collisions only
+Returns the link position of the triggered event for touches and collisions only
</string>
<string name="LSLTipText_llDie">
llDie()
-deletes the object
+Deletes the object
</string>
<string name="LSLTipText_llGround">
-float llGround(vector v)
-returns the ground height below the object position + v
+float llGround(vector offset)
+Returns the ground height below the object position + offset
</string>
<string name="LSLTipText_llCloud">
-float llCloud(vector v)
-returns the cloud density at the object position + v
+float llCloud(vector offset)
+Returns the cloud density at the object position + offset
</string>
<string name="LSLTipText_llWind">
-vector llWind(vector v)
-returns the wind velocity at the object position + v
+vector llWind(vector offset)
+Returns the wind velocity at the object position + offset
</string>
<string name="LSLTipText_llSetStatus">
llSetStatus(integer status, integer value)
-sets status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z) to value
+Sets status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z) to value
</string>
<string name="LSLTipText_llGetStatus">
integer llGetStatus(integer status)
-gets value of status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z)
+Returns value of status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z)
</string>
<string name="LSLTipText_llSetScale">
llSetScale(vector scale)
-sets the scale
+Sets the scale of the prim
</string>
<string name="LSLTipText_llGetScale">
vector llGetScale()
-gets the scale
+Returns the scale of the prim
</string>
<string name="LSLTipText_llSetColor">
llSetColor(vector color, integer face)
-sets the color
+Sets the color on face of the prim
</string>
<string name="LSLTipText_llGetAlpha">
float llGetAlpha(integer face)
-gets the alpha
+Returns the alpha of face
</string>
<string name="LSLTipText_llSetAlpha">
llSetAlpha(float alpha, integer face)
-sets the alpha
+Sets the alpha on face
</string>
<string name="LSLTipText_llGetColor">
vector llGetColor(integer face)
-gets the color
+Returns the color on face
</string>
<string name="LSLTipText_llSetTexture">
llSetTexture(string texture, integer face)
-sets the texture of face
+Sets the texture of face or ALL_SIDES
</string>
<string name="LSLTipText_llScaleTexture">
-llScaleTexture(float scales, float scalet, integer face)
-sets the texture s, t scales for the chosen face
+llScaleTexture(float u, float v, integer face)
+Sets the texture u &amp; v scales for the chosen face or ALL_SIDES
</string>
<string name="LSLTipText_llOffsetTexture">
-llOffsetTexture(float offsets, float offsett, integer face)
-sets the texture s, t offsets for the chosen face
+llOffsetTexture(float u, float v, integer face)
+Sets the texture u &amp; v offsets for the chosen face or ALL_SIDES
</string>
<string name="LSLTipText_llRotateTexture">
llRotateTexture(float rotation, integer face)
-sets the texture rotation for the chosen face
+Sets the texture rotation for the chosen face
</string>
<string name="LSLTipText_llGetTexture">
string llGetTexture(integer face)
-gets the texture of face (if it&apos;s a texture in the object inventory, otherwise the key in a string)
+Returns a string that is the texture on face (the inventory name if it is a texture in the prim&apos;s inventory, otherwise the key)
</string>
<string name="LSLTipText_llSetPos">
llSetPos(vector pos)
-sets the position (if the script isn&apos;t physical)
+Moves the object or prim towards pos without using physics (if the script isn&apos;t physical)
</string>
<string name="LSLTipText_llGetPos">
vector llGetPos()
-gets the position (if the script isn&apos;t physical)
+Returns the position of the task in region coordinates
</string>
<string name="LSLTipText_llGetLocalPos">
vector llGetLocalPos()
-gets the position relative to the root (if the script isn&apos;t physical)
+Returns the position relative to the root
</string>
<string name="LSLTipText_llSetRot">
llSetRot(rotation rot)
-sets the rotation (if the script isn&apos;t physical)
+Sets the rotation
</string>
<string name="LSLTipText_llGetRot">
rotation llGetRot()
-gets the rotation (if the script isn&apos;t physical)
+Returns the rotation relative to the region&apos;s axes
</string>
<string name="LSLTipText_llGetLocalRot">
rotation llGetLocalRot()
-gets the rotation local to the root (if the script isn&apos;t physical)
+Returns the rotation local to the root
</string>
<string name="LSLTipText_llSetForce">
llSetForce(vector force, integer local)
-sets force on object, in local coords if local == TRUE (if the script is physical)
+Applies force to the object (if the script is physical), in local coords if local == TRUE
</string>
<string name="LSLTipText_llGetForce">
vector llGetForce()
-gets the force (if the script is physical)
+Returns the force (if the script is physical)
</string>
<string name="LSLTipText_llTarget">
integer llTarget(vector position, float range)
-set positions within range of position as a target and return an ID for the target
+Sets positions within range of position as a target and return an ID for the target
</string>
<string name="LSLTipText_llTargetRemove">
llTargetRemove(integer number)
-removes target number
+Removes positional target number registered with llTarget
</string>
<string name="LSLTipText_llRotTarget">
integer llRotTarget(rotation rot, float error)
-set rotations with error of rot as a rotational target and return an ID for the rotational target
+Set rotations with error of rot as a rotational target and return an ID for the rotational target
</string>
<string name="LSLTipText_llRotTargetRemove">
llRotTargetRemove(integer number)
-removes rotational target number
+Removes rotational target number registered with llRotTarget
</string>
<string name="LSLTipText_llMoveToTarget">
llMoveToTarget(vector target, float tau)
-critically damp to target in tau seconds (if the script is physical)
+Critically damps to target in tau seconds (if the script is physical)
</string>
<string name="LSLTipText_llStopMoveToTarget">
llStopMoveToTarget()
@@ -593,83 +595,83 @@ Stops critically damped motion
</string>
<string name="LSLTipText_llApplyImpulse">
llApplyImpulse(vector force, integer local)
-applies impulse to object, in local coords if local == TRUE (if the script is physical)
+Applies impulse to object (if the script is physical), in local coords if local == TRUE
</string>
<string name="LSLTipText_llApplyRotationalImpulse">
llApplyRotationalImpulse(vector force, integer local)
-applies rotational impulse to object, in local coords if local == TRUE (if the script is physical)
+Applies rotational impulse to object (if the script is physical), in local coords if local == TRUE
</string>
<string name="LSLTipText_llSetTorque">
llSetTorque(vector torque, integer local)
-sets the torque of object, in local coords if local == TRUE (if the script is physical)
+Sets the torque of object (if the script is physical), in local coords if local == TRUE
</string>
<string name="LSLTipText_llGetTorque">
vector llGetTorque()
-gets the torque (if the script is physical)
+Returns the torque (if the script is physical)
</string>
<string name="LSLTipText_llSetForceAndTorque">
llSetForceAndTorque(vector force, vector torque, integer local)
-sets the force and torque of object, in local coords if local == TRUE (if the script is physical)
+Sets the force and torque of object (if the script is physical), in local coords if local == TRUE
</string>
<string name="LSLTipText_llGetVel">
vector llGetVel()
-gets the velocity
+Returns the velocity of the object
</string>
<string name="LSLTipText_llGetAccel">
vector llGetAccel()
-gets the acceleration
+Returns the acceleration of the object relative to the region&apos;s axes
</string>
<string name="LSLTipText_llGetOmega">
vector llGetOmega()
-gets the omega
+Returns the rotation velocity in radians per second
</string>
<string name="LSLTipText_llGetTimeOfDay">
float llGetTimeOfDay()
-gets the time in seconds since [SECOND_LIFE] server midnight (or since server up-time; whichever is smaller)
+Returns the time in seconds since [SECOND_LIFE] server midnight or since region up-time, whichever is smaller
</string>
<string name="LSLTipText_llGetWallclock">
float llGetWallclock()
-gets the time in seconds since midnight
+Returns the time in seconds since midnight California Pacific time (PST/PDT)
</string>
<string name="LSLTipText_llGetTime">
float llGetTime()
-gets the time in seconds since creation
+Returns the time in seconds since the last region reset, script reset, or call to either llResetTime or llGetAndResetTime
</string>
<string name="LSLTipText_llResetTime">
llResetTime()
-sets the time to zero
+Sets the script timer to zero
</string>
<string name="LSLTipText_llGetAndResetTime">
float llGetAndResetTime()
-gets the time in seconds since creation and sets the time to zero
+Returns the script time in seconds and then resets the script timer to zero
</string>
<string name="LSLTipText_llSound">
llSound(string sound, float volume, integer queue, integer loop)
-plays sound at volume and whether it should loop or not
+Plays sound at volume and whether it should loop or not
</string>
<string name="LSLTipText_llPlaySound">
llPlaySound(string sound, float volume)
-plays attached sound once at volume (0.0 - 1.0)
+Plays attached sound once at volume (0.0 - 1.0)
</string>
<string name="LSLTipText_llLoopSound">
llLoopSound(string sound, float volume)
-plays attached sound looping indefinitely at volume (0.0 - 1.0)
+Plays attached sound looping indefinitely at volume (0.0 - 1.0)
</string>
<string name="LSLTipText_llLoopSoundMaster">
llLoopSoundMaster(string sound, float volume)
-plays attached sound looping at volume (0.0 - 1.0), declares it a sync master
+Plays attached sound looping at volume (0.0 - 1.0), declares it a sync master
</string>
<string name="LSLTipText_llLoopSoundSlave">
llLoopSoundSlave(string sound, float volume)
-plays attached sound looping at volume (0.0 - 1.0), synced to most audible sync master
+Plays attached sound looping at volume (0.0 - 1.0), synced to most audible sync master
</string>
<string name="LSLTipText_llPlaySoundSlave">
llPlaySoundSlave(string sound, float volume)
-plays attached sound once at volume (0.0 - 1.0), synced to next loop of most audible sync master
+Plays attached sound once at volume (0.0 - 1.0), synced to next loop of most audible sync master
</string>
<string name="LSLTipText_llTriggerSound">
llTriggerSound(string sound, float volume)
-plays sound at volume (0.0 - 1.0), centered at but not attached to object
+Plays sound at volume (0.0 - 1.0), centered at but not attached to object
</string>
<string name="LSLTipText_llStopSound">
llStopSound()
@@ -677,143 +679,143 @@ Stops currently attached sound
</string>
<string name="LSLTipText_llPreloadSound">
llPreloadSound(string sound)
-preloads a sound on viewers within range
+Preloads a sound on viewers within range
</string>
<string name="LSLTipText_llGetSubString">
string llGetSubString(string src, integer start, integer end)
-returns the indicated substring
+Returns the indicated substring
</string>
<string name="LSLTipText_llDeleteSubString">
string llDeleteSubString(string src, integer start, integer end)
-removes the indicated substring and returns the result
+Removes the indicated substring and returns the result
</string>
<string name="LSLTipText_llInsertString">
string llInsertString(string dst, integer position, string src)
-inserts src into dst at position and returns the result
+Returns a destination string dst with the string src inserted starting at position pos
</string>
<string name="LSLTipText_llToUpper">
string llToUpper(string src)
-convert src to all upper case and returns the result
+Returns a string that is src with all upper-case characters
</string>
<string name="LSLTipText_llToLower">
string llToLower(string src)
-convert src to all lower case and returns the result
+Returns a string that is src with all lower-case characters
</string>
<string name="LSLTipText_llGiveMoney">
llGiveMoney(key destination, integer amount)
-transfer amount of money from script owner to destination
+Transfers amount of L$ from script owner to destination
</string>
<string name="LSLTipText_llMakeExplosion">
llMakeExplosion(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)
-Make a round explosion of particles
+Makes a round explosion of particles
</string>
<string name="LSLTipText_llMakeFountain">
llMakeFountain(integer particles, float scale, float vel, float lifetime, float arc, integer bounce, string texture, vector offset, float bounce_offset)
-Make a fountain of particles
+Makes a fountain of particles
</string>
<string name="LSLTipText_llMakeSmoke">
llMakeSmoke(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)
-Make smoke like particles
+Makes smoke like particles
</string>
<string name="LSLTipText_llMakeFire">
llMakeFire(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)
-Make fire like particles
+Makes fire like particles
</string>
<string name="LSLTipText_llRezObject">
llRezObject(string inventory, vector pos, vector vel, rotation rot, integer param)
-Instanciate owners inventory object at pos with velocity vel and rotation rot with start parameter param
+Instantiates owner&apos;s inventory object at pos with velocity vel and rotation rot with start parameter param
</string>
<string name="LSLTipText_llLookAt">
-llLookAt(vector target, F32 strength, F32 damping)
-Cause object name to point it&apos;s forward axis towards target
+llLookAt(vector target, float strength, float damping)
+Causes object to point its up axis (positive z) towards target, while keeping its forward axis (positive x) below the horizon
</string>
<string name="LSLTipText_llStopLookAt">
llStopLookAt()
-Stop causing object name to point at a target
+Stops causing object to point at a target
</string>
<string name="LSLTipText_llSetTimerEvent">
llSetTimerEvent(float sec)
-Cause the timer event to be triggered every sec seconds
+Causes the timer event to be triggered a maximum of once every sec seconds
</string>
<string name="LSLTipText_llSleep">
llSleep(float sec)
-Put script to sleep for sec seconds
+Puts the script to sleep for sec seconds
</string>
<string name="LSLTipText_llGetMass">
float llGetMass()
-Get the mass of task name that script is attached to
+Returns the mass of object that the script is attached to
</string>
<string name="LSLTipText_llCollisionFilter">
llCollisionFilter(string name, key id, integer accept)
-if accept == TRUE, only accept collisions with objects name and id (either is optional), otherwise with objects not name or id
+Sets the collision filter, exclusively or inclusively. If accept == TRUE, only accept collisions with objects name and id (either is optional), otherwise with objects not name or id
</string>
<string name="LSLTipText_llTakeControls">
llTakeControls(integer controls, integer accept, integer pass_on)
-Take controls from agent task has permissions for. If (accept == (controls &amp; input)), send input to task. If pass_on send to agent also.
+Allows for intercepting keyboard and mouse clicks from the agent the script has permissions for
</string>
<string name="LSLTipText_llReleaseControls">
llReleaseControls()
-Stop taking inputs
+Stops taking inputs that were taken with llTakeControls
</string>
<string name="LSLTipText_llAttachToAvatar">
-llAttachToAvatar(integer attachment)
-Attach to avatar task has permissions for at point attachment
+llAttachToAvatar(integer attach_point)
+Attaches the object to the avatar who has granted permission to the script
</string>
<string name="LSLTipText_llDetachFromAvatar">
llDetachFromAvatar()
-Drop off of avatar
+Detaches object from avatar
</string>
<string name="LSLTipText_llTakeCamera">
llTakeCamera(key avatar)
-Move avatar&apos;s viewpoint to task
+Moves avatar&apos;s viewpoint to task
</string>
<string name="LSLTipText_llReleaseCamera">
llReleaseCamera(key avatar)
-Return camera to agent
+Returns camera to agent avatar
</string>
<string name="LSLTipText_llGetOwner">
key llGetOwner()
-Returns the owner of the task
+Returns the object owner&apos;s UUID
</string>
<string name="LSLTipText_llInstantMessage">
llInstantMessage(key user, string message)
-IMs message to the user
+Sends the specified string as an Instant Message to the user
</string>
<string name="LSLTipText_llEmail">
llEmail(string address, string subject, string message)
-Sends email to address with subject and message
+Sends an email to address with the subject and message
</string>
<string name="LSLTipText_llGetNextEmail">
llGetNextEmail(string address, string subject)
-Get the next waiting email with appropriate address and/or subject (if blank they are ignored)
+Gets the next waiting email that comes from address, with specified subject
</string>
<string name="LSLTipText_llGetKey">
key llGetKey()
-Get the key for the task the script is attached to
+Returns the key of the prim the script is attached to
</string>
<string name="LSLTipText_llSetBuoyancy">
llSetBuoyancy(float buoyancy)
-Set the tasks buoyancy (0 is none, &lt; 1.0 sinks, 1.0 floats, > 1.0 rises)
+Sets the buoyancy of the task or object (0 is disabled, &lt; 1.0 sinks, 1.0 floats, &gt; 1.0 rises)
</string>
<string name="LSLTipText_llSetHoverHeight">
llSetHoverHeight(float height, integer water, float tau)
-Critically damps to a height (either above ground level or above the higher of land and water if water == TRUE)
+Critically damps to a height above the ground (or water) in tau seconds
</string>
<string name="LSLTipText_llStopHover">
llStopHover()
-Stop hovering to a height
+Stops hovering to a height
</string>
<string name="LSLTipText_llMinEventDelay">
llMinEventDelay(float delay)
-Set the minimum time between events being handled
+Sets the minimum time between events being handled
</string>
<string name="LSLTipText_llSoundPreload">
llSoundPreload(string sound)
-preloads a sound on viewers within range
+Preloads a sound on viewers within range
</string>
<string name="LSLTipText_llRotLookAt">
-llRotLookAt(rotation target, F32 strength, F32 damping)
-Cause object name to point it&apos;s forward axis towards target
+llRotLookAt(rotation target, float strength, float damping)
+Causes object name to point its forward axis towards target
</string>
<string name="LSLTipText_llStringLength">
integer llStringLength(string str)
@@ -821,84 +823,83 @@ Returns the length of string
</string>
<string name="LSLTipText_llStartAnimation">
llStartAnimation(string anim)
-Start animation anim for agent that owns object
+Starts animation anim for agent that granted PERMISSION_TRIGGER_ANIMATION if the permission has not been revoked
</string>
<string name="LSLTipText_llStopAnimation">
llStopAnimation(string anim)
-Stop animation anim for agent that owns object
+Stops animation anim for agent that granted permission
</string>
<string name="LSLTipText_llPointAt">
llPointAt(vector pos)
-Make agent that owns object point at pos
+Makes agent that owns object point at pos
</string>
<string name="LSLTipText_llStopPointAt">
llStopPointAt()
-Stop agent that owns object pointing
+Stops pointing agent that owns object
</string>
<string name="LSLTipText_llTargetOmega">
llTargetOmega(vector axis, float spinrate, float gain)
-Attempt to spin at spinrate with strength gain
+Rotates the object around axis at spinrate with strength gain
</string>
<string name="LSLTipText_llGetStartParameter">
integer llGetStartParameter()
-Get's the start paramter passed to llRezObject
+Returns an integer that is the script start/rez parameter
</string>
<string name="LSLTipText_llGodLikeRezObject">
llGodLikeRezObject(key inventory, vector pos)
-rez directly off of a UUID if owner has dog-bit set
+Rezzes directly off of UUID if owner is in God Mode
</string>
<string name="LSLTipText_llRequestPermissions">
llRequestPermissions(key agent, integer perm)
-ask agent to allow the script to do perm (NB: Debit, ownership, link, joint, and permission requests can only go to the task's owner)
+Asks the agent for permission to run certain classes of functions
</string>
<string name="LSLTipText_llGetPermissionsKey">
key llGetPermissionsKey()
-Return agent that permissions are enabled for. NULL_KEY if not enabled
+Returns the key of the avatar that last granted permissions to the script
</string>
<string name="LSLTipText_llGetPermissions">
integer llGetPermissions()
-return what permissions have been enabled
+Returns an integer bitfield with the permissions that have been granted
</string>
<string name="LSLTipText_llGetLinkNumber">
integer llGetLinkNumber()
-Returns what number in a link set the script is attached to (0 means no link, 1 the root, 2 for first child, etc)
+Returns the link number of the prim containing the script (0 means not linked, 1 the prim is the root, 2 the prim is the first child, etc)
</string>
<string name="LSLTipText_llSetLinkColor">
llSetLinkColor(integer linknumber, vector color, integer face)
-If a task exists in the link chain at linknumber, set face to color
+Sets face to color if a task exists in the link chain at linknumber
</string>
<string name="LSLTipText_llCreateLink">
llCreateLink(key target, integer parent)
-Attempt to link task script is attached to and target (requires permission PERMISSION_CHANGE_LINKS be set). If parent == TRUE, task script is attached to is the root
+Attempts to link the script&apos;s object with the target (requires that PERMISSION_CHANGE_LINKS be granted). If parent == TRUE, then the script&apos;s object becomes the root
</string>
<string name="LSLTipText_llBreakLink">
llBreakLink(integer linknum)
-Delinks the task with the given link number (requires permission PERMISSION_CHANGE_LINKS be set)
+Delinks the prim with the given link number in a linked object set (requires that PERMISSION_CHANGE_LINKS be granted)
</string>
<string name="LSLTipText_llBreakAllLinks">
llBreakAllLinks()
-Delinks all tasks in the link set (requires permission PERMISSION_CHANGE_LINKS be set)
+Delinks all prims in the link set (requires that PERMISSION_CHANGE_LINKS be granted)
</string>
<string name="LSLTipText_llGetLinkKey">
-key llGetLinkKey(integer linknum)
-Get the key of linknumber in link set
+key llGetLinkKey(integer linknumber)
+Returns the key of the linked prim linknumber
</string>
<string name="LSLTipText_llGetLinkName">
-string llGetLinkName(integer linknum)
-Get the name of linknumber in link set
+string llGetLinkName(integer linknumber)
+Returns the name of linknumber in a link set
</string>
<string name="LSLTipText_llGetInventoryNumber">
integer llGetInventoryNumber(integer type)
-Get the number of items of a given type in the task's inventory.
-Valid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ALL
+Returns the number of items of a given type (INVENTORY_* flag) in the prim&apos;s inventory
</string>
<string name="LSLTipText_llGetInventoryName">
string llGetInventoryName(integer type, integer number)
-Get the name of the inventory item number of type
+Returns the name of the inventory item number of a given type
</string>
<string name="LSLTipText_llSetScriptState">
llSetScriptState(string name, integer run)
-Control the state of a script name.
+Sets the running state of the specified script
</string>
<string name="LSLTipText_llGetEnergy">
float llGetEnergy()
@@ -906,56 +907,55 @@ Returns how much energy is in the object as a percentage of maximum
</string>
<string name="LSLTipText_llGiveInventory">
llGiveInventory(key destination, string inventory)
-Give inventory to destination
+Gives inventory to destination
</string>
<string name="LSLTipText_llRemoveInventory">
-llRemoveInventory(string inventory)
-Remove the named inventory item
+llRemoveInventory(string item)
+Removes the named inventory item
</string>
<string name="LSLTipText_llSetText">
llSetText(string text, vector color, float alpha)
-Set text floating over object
+Displays text that hovers over the prim with specific color and translucency specified with alpha
</string>
<string name="LSLTipText_llWater">
-float llWater(vector v)
-returns the water height below the object position + v
+float llWater(vector offset)
+Returns the water height below the object position + offset
</string>
<string name="LSLTipText_llPassTouches">
llPassTouches(integer pass)
-if pass == TRUE, touches are passed from children on to parents (default is FALSE)
+If pass == TRUE, touches are passed from children on to parents
</string>
<string name="LSLTipText_llRequestAgentData">
key llRequestAgentData(key id, integer data)
-Requests data about agent id. When data is available the dataserver event will be raised
+Requests data about agent id. When data is available the dataserver event will be raised.
</string>
<string name="LSLTipText_llRequestInventoryData">
key llRequestInventoryData(string name)
-Requests data from object's inventory object. When data is available the dataserver event will be raised
+Requests data from object&apos;s inventory object. When data is available the dataserver event will be raised.
</string>
<string name="LSLTipText_llSetDamage">
llSetDamage(float damage)
-Sets the amount of damage that will be done to an object that this task hits. Task will be killed.
+Sets the amount of damage that will be done when this object hits an avatar.
</string>
<string name="LSLTipText_llTeleportAgentHome">
llTeleportAgentHome(key id)
-Teleports agent on owner's land to agent's home location
+Teleports avatar on the owner&apos;s land to their home location without any warning
</string>
<string name="LSLTipText_llModifyLand">
-llModifyLand(integer action, integer size)
-Modify land with action (LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE, LAND_REVERT)
-on size (LAND_SMALL_BRUSH, LAND_MEDIUM_BRUSH, LAND_LARGE_BRUSH)
+llModifyLand(integer action, integer brush)
+Modifies land using the specified action on the specified brush size of land
</string>
<string name="LSLTipText_llCollisionSound">
llCollisionSound(string impact_sound, float impact_volume)
-Suppress default collision sounds, replace default impact sounds with impact_sound (empty string to just suppress)
+Suppresses default collision sounds, replaces default impact sounds with impact_sound at the volume impact_volume
</string>
<string name="LSLTipText_llCollisionSprite">
llCollisionSprite(string impact_sprite)
-Suppress default collision sprites, replace default impact sprite with impact_sprite (empty string to just suppress)
+Suppresses default collision sprites, replaces default impact sprite with impact_sprite (use an empty string to just suppress)
</string>
<string name="LSLTipText_llGetAnimation">
string llGetAnimation(key id)
-Get the currently playing locomotion animation for avatar id
+Returns the name of the currently playing locomotion animation for avatar id
</string>
<string name="LSLTipText_llResetScript">
llResetScript()
@@ -963,12 +963,7 @@ Resets the script
</string>
<string name="LSLTipText_llMessageLinked">
llMessageLinked(integer linknum, integer num, string str, key id)
-Sends num, str, and id to members of the link set
-(LINK_ROOT sends to root task in a linked set,
-LINK_SET sends to all tasks,
-LINK_ALL_OTHERS to all other tasks,
-LINK_ALL_CHILDREN to all children,
-LINK_THIS to the task the script it is in)
+Allows scripts in the same object to communicate. Triggers a link_message event with the same parameters num, str, and id in all scripts in the prim(s) described by linknum.
</string>
<string name="LSLTipText_llPushObject">
llPushObject(key id, vector impulse, vector ang_impulse, integer local)
@@ -976,19 +971,19 @@ Applies impulse and ang_impulse to object id
</string>
<string name="LSLTipText_llPassCollisions">
llPassCollisions(integer pass)
-if pass == TRUE, collisions are passed from children on to parents (default is FALSE)
+If pass == TRUE, collisions are passed from children on to parents (default is FALSE)
</string>
<string name="LSLTipText_llGetScriptName">
-llGetScriptName()
-Returns the script name
+string llGetScriptName()
+Returns the name of the script that this function is used in
</string>
<string name="LSLTipText_llGetNumberOfSides">
integer llGetNumberOfSides()
-Returns the number of sides
+Returns the number of faces (or sides) of the prim
</string>
<string name="LSLTipText_llAxisAngle2Rot">
rotation llAxisAngle2Rot(vector axis, float angle)
-Returns the rotation generated angle about axis
+Returns the rotation that is a generated angle about axis
</string>
<string name="LSLTipText_llRot2Axis">
vector llRot2Axis(rotation rot)
@@ -1012,19 +1007,19 @@ Returns angle between rotation a and b
</string>
<string name="LSLTipText_llGetInventoryKey">
key llGetInventoryKey(string name)
-Returns the key of the inventory name
+Returns the key that is the UUID of the inventory name
</string>
<string name="LSLTipText_llAllowInventoryDrop">
llAllowInventoryDrop(integer add)
-If add == TRUE, users without permissions can still drop inventory items onto task
+If add == TRUE, users without modify permissions can still drop inventory items onto a prim
</string>
<string name="LSLTipText_llGetSunDirection">
vector llGetSunDirection()
-Returns the sun direction on the simulator
+Returns a normalized vector of the direction of the sun in the region
</string>
<string name="LSLTipText_llGetTextureOffset">
-vector llGetTextureOffset(integer side)
-Returns the texture offset of side in the x and y components of a vector
+vector llGetTextureOffset(integer face)
+Returns the texture offset of face in the x and y components of a vector
</string>
<string name="LSLTipText_llGetTextureScale">
vector llGetTextureScale(integer side)
@@ -1036,55 +1031,57 @@ Returns the texture rotation of side
</string>
<string name="LSLTipText_llSubStringIndex">
integer llSubStringIndex(string source, string pattern)
-Finds index in source where pattern first appears (returns -1 if not found)
+Returns an integer that is the index in source where pattern first appears.
+(Returns -1 if not found)
</string>
<string name="LSLTipText_llGetOwnerKey">
key llGetOwnerKey(key id)
-Find the owner of id
+Returns the owner of object id
</string>
<string name="LSLTipText_llGetCenterOfMass">
vector llGetCenterOfMass()
-Get the object's center of mass
+Returns the prim&apos;s center of mass (unless called from the root prim, where it returns the object&apos;s center of mass)
</string>
<string name="LSLTipText_llListSort">
list llListSort(list src, integer stride, integer ascending)
-Sort the list into blocks of stride in ascending order if ascending == TRUE. Note that sort only works between same types.
+Sorts the list into blocks of stride, in ascending order if ascending == TRUE.
+The sort order is affected by type.
</string>
<string name="LSLTipText_llGetListLength">
integer llGetListLength(list src)
-Get the number of elements in the list
+Returns the number of elements in the list
</string>
<string name="LSLTipText_llList2Integer">
integer llList2Integer(list src, integer index)
-Copy the integer at index in the list
+Copies the integer at index in the list
</string>
<string name="LSLTipText_llList2Float">
float llList2Float(list src, integer index)
-Copy the float at index in the list
+Copies the float at index in the list
</string>
<string name="LSLTipText_llList2String">
string llList2String(list src, integer index)
-Copy the string at index in the list
+Copies the string at index in the list
</string>
<string name="LSLTipText_llList2Key">
key llList2Key(list src, integer index)
-Copy the key at index in the list
+Copies the key at index in the list
</string>
<string name="LSLTipText_llList2Vector">
vector llList2Vector(list src, integer index)
-Copy the vector at index in the list
+Copies the vector at index in the list
</string>
<string name="LSLTipText_llList2Rot">
rotation llList2Rot(list src, integer index)
-Copy the rotation at index in the list
+Copies the rotation at index in the list
</string>
<string name="LSLTipText_llList2List">
list llList2List(list src, integer start, integer end)
-Copy the slice of the list from start to end
+Copies the slice of the list from start to end
</string>
<string name="LSLTipText_llDeleteSubList">
list llDeleteSubList(list src, integer start, integer end)
-Remove the slice from the list and return the remainder
+Removes the slice from start to end and returns the remainder of the list
</string>
<string name="LSLTipText_llGetListEntryType">
integer llGetListEntryType(list src, integer index)
@@ -1093,11 +1090,11 @@ Returns the type of the index entry in the list
</string>
<string name="LSLTipText_llList2CSV">
string llList2CSV(list src)
-Create a string of comma separated values from list
+Creates a string of comma separated values from list
</string>
<string name="LSLTipText_llCSV2List">
list llCSV2List(string src)
-Create a list from a string of comma separated values
+Creates a list from a string of comma separated values
</string>
<string name="LSLTipText_llListRandomize">
list llListRandomize(list src, integer stride)
@@ -1105,80 +1102,83 @@ Returns a randomized list of blocks of size stride
</string>
<string name="LSLTipText_llList2ListStrided">
list llList2ListStrided(list src, integer start, integer end, integer stride)
-Copy the strided slice of the list from start to end
+Copies the strided slice of the list from start to end
</string>
<string name="LSLTipText_llGetRegionCorner">
vector llGetRegionCorner()
-Returns a vector with the south west corner x,y position of the region the object is in
+Returns a vector in meters that is the global location of the south-west corner of the region which the object is in
</string>
<string name="LSLTipText_llListInsertList">
list llListInsertList(list dest, list src, integer start)
-Inserts src into dest at position start
+Returns a list that contains all the elements from dest but with the elements from src inserted at position start
</string>
<string name="LSLTipText_llListFindList">
integer llListFindList(list src, list test)
-Returns the start of the first instance of test in src, -1 if not found
+Returns the index of the first instance of test in src.
+(Returns -1 if not found)
</string>
<string name="LSLTipText_llGetObjectName">
string llGetObjectName()
-Returns the name of the object script is attached to
+Returns the name of the prim which the script is attached to
</string>
<string name="LSLTipText_llSetObjectName">
llSetObjectName(string name)
-Sets the objects name
+Sets the prim&apos;s name to the name parameter
</string>
<string name="LSLTipText_llGetDate">
string llGetDate()
-Gets the date as YYYY-MM-DD
+Returns the current date in the UTC time zone in the format YYYY-MM-DD
</string>
<string name="LSLTipText_llEdgeOfWorld">
integer llEdgeOfWorld(vector pos, vector dir)
-Checks to see whether the border hit by dir from pos is the edge of the world (has no neighboring simulator)
+Checks to see whether the border hit by dir from pos is the edge of the world (has no neighboring region)
</string>
<string name="LSLTipText_llGetAgentInfo">
integer llGetAgentInfo(key id)
-Gets information about agent ID.
-Returns AGENT_FLYING, AGENT_ATTACHMENTS, AGENT_SCRIPTED, AGENT_SITTING, AGENT_ON_OBJECT, AGENT_MOUSELOOK, AGENT_AWAY, AGENT_BUSY, AGENT_TYPING, AGENT_CROUCHING, AGENT_ALWAYS_RUN, AGENT_WALKING, AGENT_IN_AIR and/or AGENT_AUTOPILOT.
+Returns an integer bitfield containing the agent information about id.
+Returns AGENT_FLYING, AGENT_ATTACHMENTS, AGENT_SCRIPTED, AGENT_SITTING, AGENT_ON_OBJECT, AGENT_MOUSELOOK, AGENT_AWAY, AGENT_BUSY, AGENT_TYPING, AGENT_CROUCHING, AGENT_ALWAYS_RUN, AGENT_WALKING and/or AGENT_IN_AIR.
</string>
<string name="LSLTipText_llAdjustSoundVolume">
llAdjustSoundVolume(float volume)
-adjusts volume of attached sound (0.0 - 1.0)
+Adjusts volume of attached sound (0.0 - 1.0)
</string>
<string name="LSLTipText_llSetSoundQueueing">
llSetSoundQueueing(integer queue)
-determines whether attached sound calls wait for the current sound to finish (0 = no [default], nonzero = yes)
+Sets whether attached sounds wait for the current sound to finish (If queue == TRUE then queuing is enabled, if FALSE queuing is disabled [default])
</string>
<string name="LSLTipText_llSetSoundRadius">
llSetSoundRadius(float radius)
-establishes a hard cut-off radius for audibility of scripted sounds (both attached and triggered)
+Establishes a hard cut-off radius for audibility of scripted sounds (both attached and triggered)
</string>
<string name="LSLTipText_llKey2Name">
string llKey2Name(key id)
-Returns the name of the object key, iff the object is in the current simulator, otherwise the empty string
+Returns the name of the prim or avatar specified by id.
+(The id must be a valid rezzed prim or avatar key in the current simulator, otherwise an empty string is returned.)
</string>
<string name="LSLTipText_llSetTextureAnim">
llSetTextureAnim(integer mode, integer face, integer sizex, integer sizey, float start, float length, float rate)
-Animate the texture on the specified face/faces
+Animates the texture on the specified face/faces
</string>
<string name="LSLTipText_llTriggerSoundLimited">
-llTriggerSoundLimited(string sound, float volume, vector tne, vector bsw)
-plays sound at volume (0.0 - 1.0), centered at but not attached to object, limited to AABB defined by vectors top-north-east and bottom-south-west
+llTriggerSoundLimited(string sound, float volume, vector top_north_east, vector bottom_south_west)
+Plays sound at volume (0.0 - 1.0), centered at but not attached to object, limited to the box defined by vectors top_north_east and bottom_south_west
</string>
<string name="LSLTipText_llEjectFromLand">
-llEjectFromLand(key pest)
-Ejects pest from land that you own
+llEjectFromLand(key avatar)
+Ejects avatar from the parcel
</string>
<string name="LSLTipText_llParseString2List">
list llParseString2List(string src, list separators, list spacers)
-Breaks src into a list, discarding separators, keeping spacers (separators and spacers must be lists of strings, maximum of 8 each)
+Breaks src into a list, discarding separators, keeping spacers
+(separators and spacers must be lists of strings, maximum of 8 each)
</string>
<string name="LSLTipText_llOverMyLand">
integer llOverMyLand(key id)
-Returns TRUE if id is over land owner of object owns, FALSE otherwise
+Returns TRUE if id is over land owned by the script owner, otherwise FALSE
</string>
<string name="LSLTipText_llGetLandOwnerAt">
key llGetLandOwnerAt(vector pos)
-Returns the key of the land owner, NULL_KEY if public
+Returns the key of the land owner, returns NULL_KEY if public
</string>
<string name="LSLTipText_llGetNotecardLine">
key llGetNotecardLine(string name, integer line)
@@ -1186,131 +1186,130 @@ Returns line line of notecard name via the dataserver event
</string>
<string name="LSLTipText_llGetAgentSize">
vector llGetAgentSize(key id)
-If the agent is in the same sim as the object, returns the size of the avatar
+If the avatar is in the same region, returns the size of the bounding box of the requested avatar by id, otherwise returns ZERO_VECTOR
</string>
<string name="LSLTipText_llSameGroup">
integer llSameGroup(key id)
-Returns TRUE if ID is in the same sim and has the same active group, otherwise FALSE
+Returns TRUE if avatar id is in the same region and has the same active group, otherwise FALSE
</string>
<string name="LSLTipText_llUnSit">
key llUnSit(key id)
-If agent identified by id is sitting on the object the script is attached to or is over land owned by the objects owner, the agent is forced to stand up
+If avatar identified by id is sitting on the object the script is attached to or is over land owned by the object&apos;s owner, the avatar is forced to stand up
</string>
<string name="LSLTipText_llGroundSlope">
-vector llGroundSlope(vector v)
-returns the ground slope below the object position + v
+vector llGroundSlope(vector offset)
+Returns the ground slope below the object position + offset
</string>
<string name="LSLTipText_llGroundNormal">
-vector llGroundNormal(vector v)
-returns the ground normal below the object position + v
+vector llGroundNormal(vector offset)
+Returns the ground normal below the object position + offset
</string>
<string name="LSLTipText_llGroundContour">
-vector llGroundCountour(vector v)
-returns the ground contour below the object position + v
+vector llGroundCountour(vector offset)
+Returns the ground contour direction below the object position + offset
</string>
<string name="LSLTipText_llGetAttached">
integer llGetAttached()
-returns the object attachment point or 0 if not attached
+Returns the object&apos;s attachment point, or 0 if not attached
</string>
<string name="LSLTipText_llGetFreeMemory">
integer llGetFreeMemory()
-returns the available heap space for the current script
+Returns the number of free bytes of memory the script can use
</string>
<string name="LSLTipText_llGetRegionName">
string llGetRegionName()
-returns the current region name
+Returns the current region name
</string>
<string name="LSLTipText_llGetRegionTimeDilation">
float llGetRegionTimeDilation()
-returns the current time dilation as a float between 0 and 1
+Returns the current time dilation as a float between 0.0 (full dilation) and 1.0 (no dilation)
</string>
<string name="LSLTipText_llGetRegionFPS">
float llGetRegionFPS()
-returns the mean region frames per second
+Returns the mean region frames per second
</string>
<string name="LSLTipText_llParticleSystem">
llParticleSystem(list rules)
-Creates a particle system based on rules. Empty list removes particle system from object.
+Creates a particle system based on rules. An empty list removes the particle system.
List format is [ rule1, data1, rule2, data2 . . . rulen, datan ]
</string>
<string name="LSLTipText_llGroundRepel">
llGroundRepel(float height, integer water, float tau)
-Critically damps to height if within height*0.5 of level (either above ground level or above the higher of land and water if water == TRUE)
+Critically damps to height if within height*0.5 of level (either above ground level, or above the higher of land and water if water == TRUE)
</string>
<string name="LSLTipText_llGiveInventoryList">
-llGiveInventoryList(key destination, string category, list inventory)
-Give inventory to destination in a new category
+llGiveInventoryList(key target, string folder, list inventory)
+Gives inventory items to target, creating a new folder to put them in
</string>
<string name="LSLTipText_llSetVehicleType">
llSetVehicleType(integer type)
-sets vehicle to one of the default types
+Sets the vehicle to one of the default types
</string>
<string name="LSLTipText_llSetVehicleFloatParam">
llSetVehicleFloatParam(integer param, float value)
-sets the specified vehicle float parameter
+Sets the specified vehicle float parameter
</string>
<string name="LSLTipText_llSetVehicleVectorParam">
llSetVehicleVectorParam(integer param, vector vec)
-sets the specified vehicle vector parameter
+Sets the specified vehicle vector parameter
</string>
<string name="LSLTipText_llSetVehicleRotationParam">
llSetVehicleVectorParam(integer param, rotation rot)
-sets the specified vehicle rotation parameter
+Sets the specified vehicle rotation parameter
</string>
<string name="LSLTipText_llSetVehicleFlags">
llSetVehicleFlags(integer flags)
-sets the enabled bits in 'flags'
+Sets the enabled bits in &apos;flags&apos;
</string>
<string name="LSLTipText_llRemoveVehicleFlags">
llRemoveVehicleFlags(integer flags)
-removes the enabled bits in 'flags'
+Removes the enabled bits in &apos;flags&apos;
</string>
<string name="LSLTipText_llSitTarget">
llSitTarget(vector offset, rotation rot)
-Set the sit location for this object (if offset == &lt;0,0,0&gt; clear it)
+Sets the sit location for the prim. If offset == &lt;0,0,0&gt; then the sit target is removed.
</string>
<string name="LSLTipText_llAvatarOnSitTarget">
key llAvatarOnSitTarget()
-If an avatar is sitting on the sit target, return the avatar's key, NULL_KEY otherwise
+If an avatar is seated on the sit target, returns the avatar&apos;s key, otherwise NULL_KEY
</string>
<string name="LSLTipText_llAddToLandPassList">
llAddToLandPassList(key avatar, float hours)
-Add avatar to the land pass list for hours
+Adds avatar to the land pass list for hours, or indefinitely if hours is 0
</string>
<string name="LSLTipText_llSetTouchText">
llSetTouchText(string text)
-Displays text in pie menu that acts as a touch
+Displays text rather than the default &apos;Touch&apos; in the pie menu
</string>
<string name="LSLTipText_llSetSitText">
llSetSitText(string text)
-Displays text rather than sit in pie menu
+Displays text rather than the default &apos;Sit Here&apos; in the pie menu
</string>
<string name="LSLTipText_llSetCameraEyeOffset">
llSetCameraEyeOffset(vector offset)
-Sets the camera eye offset used in this object if an avatar sits on it
+Sets the camera eye offset for avatars that sit on the object
</string>
<string name="LSLTipText_llSetCameraAtOffset">
llSetCameraAtOffset(vector offset)
-Sets the camera at offset used in this object if an avatar sits on it
+Sets the point the camera is looking at to offset for avatars that sit on the object
</string>
<string name="LSLTipText_llDumpList2String">
string llDumpList2String(list src, string separator)
-Write the list out in a single string using separator between values
+Returns the list in a single string, using separator between the entries
</string>
<string name="LSLTipText_llScriptDanger">
integer llScriptDanger(vector pos)
-Returns true if pos is over public land, sandbox land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts
+Returns TRUE if pos is over public land, sandbox land, land that doesn&apos;t allow everyone to edit and build, or land that doesn&apos;t allow outside scripts
</string>
<string name="LSLTipText_llDialog">
llDialog(key avatar, string message, list buttons, integer chat_channel
-Shows a dialog box on the avatar's screen with the message.
-Up to 12 strings in the list form buttons.
-If a button is clicked, the name is chatted on chat_channel.
+Shows a dialog box on the avatar&apos;s screen with a message and up to 12 buttons.
+If a button is pressed, the avatar says the text of the button label on chat_channel.
</string>
<string name="LSLTipText_llVolumeDetect">
llVolumeDetect(integer detect)
-If detect = TRUE, object becomes phantom but triggers collision_start and collision_end events when other objects start and stop interpenetrating.
-Must be applied to the root object.
+If detect = TRUE, object works much like Phantom, but triggers collision_start and collision_end events when other objects start and stop interpenetrating.
+Must be applied to the root prim.
</string>
<string name="LSLTipText_llResetOtherScript">
llResetOtherScript(string name)
@@ -1318,110 +1317,107 @@ Resets script name
</string>
<string name="LSLTipText_llGetScriptState">
integer llGetScriptState(string name)
-Resets TRUE if script name is running
+Returns TRUE if the script name is running
</string>
<string name="LSLTipText_llRemoteLoadScript">
-Deprecated. Please use llRemoteLoadScriptPin instead.
+DEPRECATED! Please use llRemoteLoadScriptPin instead.
</string>
<string name="LSLTipText_llSetRemoteScriptAccessPin">
llSetRemoteScriptAccessPin(integer pin)
-If pin is set to a non-zero number, the task will accept remote script loads via llRemoteLoadScriptPin if it passes in the correct pin.
-Othersise, llRemoteLoadScriptPin is ignored.
+If pin is set to a non-zero number, allows a prim to have scripts remotely loaded via llRemoteLoadScriptPin when it passes in the correct pin. Otherwise, llRemoteLoadScriptPin is ignored.
</string>
<string name="LSLTipText_llRemoteLoadScriptPin">
llRemoteLoadScriptPin(key target, string name, integer pin, integer running, integer start_param)
-If the owner of the object this script is attached can modify target,
-they are in the same region, and the matching pin is used,
-copy script name onto target,
-if running == TRUE, start the script with param.
+Copies script name onto target, if the owner of this scripted object can modify target and is in the same region, and the matching pin is used.
+If running == TRUE, starts the script with start_param
</string>
<string name="LSLTipText_llOpenRemoteDataChannel">
llOpenRemoteDataChannel()
-Creates a channel to listen for XML-RPC calls. Will trigger a remote_data event with channel id once it is available.
+Creates a channel to listen for XML-RPC calls, and will trigger a remote_data event with channel id once it is available
</string>
<string name="LSLTipText_llSendRemoteData">
key llSendRemoteData(key channel, string dest, integer idata, string sdata)
-Send an XML-RPC request to dest through channel with payload of channel (in a string), integer idata and string sdata.
-A message identifier key is returned.
-An XML-RPC reply will trigger a remote_data event and reference the message id.
-The message_id is returned.
+Sends an XML-RPC request to dest through channel with payload of channel (in a string), integer idata and string sdata.
+Returns a key that is the message_id for the resulting remote_data events.
</string>
<string name="LSLTipText_llRemoteDataReply">
llRemoteDataReply(key channel, key message_id, string sdata, integer idata)
-Send an XML-RPC reply to message_id on channel with payload of string sdata and integer idata
+Sends an XML-RPC reply to message_id on channel with payload of string sdata and integer idata
</string>
<string name="LSLTipText_llCloseRemoteDataChannel">
llCloseRemoteDataChannel(key channel)
-Closes XML-RPC channel.
+Closes XML-RPC channel
</string>
<string name="LSLTipText_llMD5String">
string llMD5String(string src, integer nonce)
-Performs a RSA Data Security, Inc. MD5 Message-Digest Algorithm on string with nonce. Returns a 32 character hex string.
+Returns a string of 32 hex characters that is a RSA Data Security, Inc. MD5 Message-Digest Algorithm of src with nonce
</string>
<string name="LSLTipText_llSetPrimitiveParams">
llSetPrimitiveParams(list rules)
-Set primitive parameters based on rules.
+Sets the prim&apos;s parameters according to rules
</string>
<string name="LSLTipText_llStringToBase64">
string llStringToBase64(string str)
-Converts a string to the Base 64 representation of the string.
+Converts a string to the Base64 representation of the string
</string>
<string name="LSLTipText_llBase64ToString">
string llBase64ToString(string str)
-Converts a Base 64 string to a conventional string. If the conversion creates any unprintable characters, they are converted to spaces.
+Converts a Base64 string to a conventional string.
+If the conversion creates any unprintable characters, they are converted to spaces.
</string>
<string name="LSLTipText_llXorBase64Strings">
string llXorBase64Strings(string s1, string s2)
-DEPRECATED! Please use llXorBase64StringsCorrect instead!! Incorrectly performs an exclusive or on two Base 64 strings and returns a Base 64 string. s2 repeats if it is shorter than s1. Retained for backwards compatability.
+DEPRECATED! Please use llXorBase64StringsCorrect instead.
+Incorrectly performs an exclusive or on two Base64 strings and returns a Base64 string. s2 repeats if it is shorter than s1. Retained for backwards compatability.
</string>
<string name="LSLTipText_llRemoteDataSetRegion">
llRemoteDataSetRegion()
-If an object using remote data channels changes regions, you must call this function to reregister the remote data channels.
-You do not need to make this call if you don't change regions.
+DEPRECATED! Please use llOpenRemoteDataChannel instead.
+If an object using remote data channels changes regions, you must call this function to reregister the remote data channels. This call is not needed if the prim does not change regions.
</string>
<string name="LSLTipText_llLog10">
float llLog10(float val)
-Returns the base 10 log of val if val &gt; 0, otherwise returns 0.
+Returns the base 10 logarithm of val. Returns zero if val &lt;= 0.
</string>
<string name="LSLTipText_llLog">
float llLog(float val)
-Returns the base e log of val if val &gt; 0, otherwise returns 0.
+Returns the natural logarithm of val. Returns zero if val &lt;= 0.
</string>
<string name="LSLTipText_llGetAnimationList">
list llGetAnimationList(key id)
-Gets a list of all playing animations for avatar id
+Returns a list of keys of playing animations for avatar described by id
</string>
<string name="LSLTipText_llSetParcelMusicURL">
llSetParcelMusicURL(string url)
-Sets the streaming audio URL for the parcel object is on
+Sets the streaming audio URL for the parcel which the object is on
</string>
<string name="LSLTipText_llGetRootPosition">
vector llGetRootPosition()
-Gets the global position of the root object of the object script is attached to
+Returns the position (in region coordinates) of the root prim of the object which the script is attached to
</string>
<string name="LSLTipText_llGetRootRotation">
rotation llGetRootRotation()
-Gets the global rotation of the root object of the object script is attached to
+Returns the rotation (relative to the region) of the root prim of the object which the script is attached to
</string>
<string name="LSLTipText_llGetObjectDesc">
string llGetObjectDesc()
-Returns the description of the object the script is attached to
+Returns the description of the prim the script is attached to
</string>
<string name="LSLTipText_llSetObjectDesc">
llSetObjectDesc(string name)
-Sets the object's description
+Sets the prim&apos;s description
</string>
<string name="LSLTipText_llGetCreator">
key llGetCreator()
-Returns the creator of the object
+Returns a key for the creator of the prim
</string>
<string name="LSLTipText_llGetTimestamp">
string llGetTimestamp()
-Gets the timestamp in the format: YYYY-MM-DDThh:mm:ss.ff..fZ
+Returns the timestamp in the UTC time zone in the format: YYYY-MM-DDThh:mm:ss.ff..fZ
</string>
<string name="LSLTipText_llSetLinkAlpha">
llSetLinkAlpha(integer linknumber, float alpha, integer face)
-If a prim exists in the link chain at linknumber, set face to alpha
+If a prim exists in the link chain at linknumber, sets face to alpha
</string>
<string name="LSLTipText_llGetNumberOfPrims">
integer llGetNumberOfPrims()
@@ -1429,11 +1425,11 @@ Returns the number of prims in a link set the script is attached to
</string>
<string name="LSLTipText_llGetNumberOfNotecardLines">
key llGetNumberOfNotecardLines(string name)
-Returns number of lines in notecard 'name' via the dataserver event (cast return value to integer)
+Returns number of lines in notecard name via the dataserver event (cast return value to integer)
</string>
<string name="LSLTipText_llGetBoundingBox">
list llGetBoundingBox(key object)
-Returns the bounding box around an object (including any linked prims) relative to the root prim, in a list: [ (vector) min_corner, (vector) max_corner ]
+Returns the bounding box around the object (including any linked prims) relative to its root prim, in a list in the format [ (vector) min_corner, (vector) max_corner ]
</string>
<string name="LSLTipText_llGetGeometricCenter">
vector llGetGeometricCenter()
@@ -1441,142 +1437,143 @@ Returns the geometric center of the linked set the script is attached to.
</string>
<string name="LSLTipText_llGetPrimitiveParams">
list llGetPrimitiveParams(list params)
-Gets primitive parameters specified in the params list.
+Returns the primitive parameters specified in the params list.
</string>
<string name="LSLTipText_llIntegerToBase64">
string llIntegerToBase64(integer number)
-Big endian encode of of integer as a Base64 string.
+Returns a string that is a Base64 big endian encode of number
</string>
<string name="LSLTipText_llBase64ToInteger">
integer llBase64ToInteger(string str)
-Big endian decode of a Base64 string into an integer.
+Returns an integer that is the str Base64 decoded as a big endian integer
</string>
<string name="LSLTipText_llGetGMTclock">
float llGetGMTclock()
-Gets the time in seconds since midnight in GMT
+Returns the time in seconds since midnight GMT
</string>
<string name="LSLTipText_llGetSimulatorHostname">
string llGetSimulatorHostname()
-Gets the hostname of the machine script is running on (same as string in viewer Help dialog)
+Returns the hostname of the machine which the script is running on (same as string in viewer Help dialog)
</string>
<string name="LSLTipText_llSetLocalRot">
llSetLocalRot(rotation rot)
-sets the rotation of a child prim relative to the root prim
+Sets the rotation of a child prim relative to the root prim
</string>
<string name="LSLTipText_llParseStringKeepNulls">
list llParseStringKeepNulls(string src, list separators, list spacers)
-Breaks src into a list, discarding separators, keeping spacers (separators and spacers must be lists of strings, maximum of 8 each), keeping any null values generated.
+Breaks src into a list, discarding separators, keeping spacers, keeping any null values generated.
+(separators and spacers must be lists of strings, maximum of 8 each)
</string>
<string name="LSLTipText_llRezAtRoot">
llRezAtRoot(string inventory, vector pos, vector vel, rotation rot, integer param)
-Instantiate owner's inventory object at pos with velocity vel and rotation rot with start parameter param.
-The last selected root object's location will be set to pos
+Instantiates owner&apos;s inventory object rotated to rot with its root at pos, moving at vel, using param as the start parameter
</string>
<string name="LSLTipText_llGetObjectPermMask">
integer llGetObjectPermMask(integer mask)
-Returns the requested permission mask for the root object the task is attached to.
+Returns the requested permission mask for the root object the task is attached to
</string>
<string name="LSLTipText_llSetObjectPermMask">
llSetObjectPermMask(integer mask, integer value)
-Sets the given permission mask to the new value on the root object the task is attached to.
+Sets the given permission mask to the new value on the root object the task is attached to
</string>
<string name="LSLTipText_llGetInventoryPermMask">
integer llGetInventoryPermMask(string item, integer mask)
-Returns the requested permission mask for the inventory item.
+Returns the requested permission mask for the inventory item
</string>
<string name="LSLTipText_llSetInventoryPermMask">
llSetInventoryPermMask(string item, integer mask, integer value)
-Sets the given permission mask to the new value on the inventory item.
+Sets the given permission mask to the new value on the inventory item
</string>
<string name="LSLTipText_llGetInventoryCreator">
key llGetInventoryCreator(string item)
-Returns the key for the creator of the inventory item.
+Returns a key for the creator of the inventory item
</string>
<string name="LSLTipText_llOwnerSay">
llOwnerSay(string msg)
-says msg to owner only (if owner in sim)
+Says msg to owner only. (Owner must be in the same region.)
</string>
<string name="LSLTipText_llRequestSimulatorData">
key llRequestSimulatorData(string simulator, integer data)
-Requests data about simulator. When data is available the dataserver event will be raised
+Requests data about simulator. When data is available the dataserver event will be raised.
</string>
<string name="LSLTipText_llForceMouselook">
llForceMouselook(integer mouselook)
-If mouselook is TRUE any avatar that sits on this object is forced into mouselook mode
+If mouselook is TRUE, any avatar that sits upon the prim will be forced into mouselook mode
</string>
<string name="LSLTipText_llGetObjectMass">
float llGetObjectMass(key id)
-Get the mass of the object with key id
+Returns the mass of the avatar or object in the region
</string>
<string name="LSLTipText_llListReplaceList">
list llListReplaceList(list dest, list src, integer start, integer end)
-Replaces start through end of dest with src.
+Returns a list that is dest with start through end removed and src inserted at start
</string>
<string name="LSLTipText_llLoadURL">
-llLoadURL(key avatar_id, string message, string url)
-Shows dialog to avatar avatar_id offering to load web page at URL. If user clicks yes, launches their web browser.
+llLoadURL(key avatar, string message, string url)
+Shows a dialog to avatar offering to load the web page at url with a message.
+If user clicks yes, launches the page in their web browser.
</string>
<string name="LSLTipText_llParcelMediaCommandList">
llParcelMediaCommandList(list command)
-Sends a list of commands, some with arguments, to a parcel.
+Sends a list of commands, some with arguments, to a parcel to control the playback of movies and other media
</string>
<string name="LSLTipText_llParcelMediaQuery">
list llParcelMediaQuery(list query)
-Sends a list of queries, returns a list of results.
+Returns a list containing results of the sent query
</string>
<string name="LSLTipText_llModPow">
integer llModPow(integer a, integer b, integer c)
-Returns a raised to the b power, mod c. ( (a**b)%c ). b is capped at 0xFFFF (16 bits).
+Returns a raised to the b power, mod c. ( (a**b)%c )
+b is capped at 0xFFFF (16 bits).
</string>
<string name="LSLTipText_llGetInventoryType">
integer llGetInventoryType(string name)
-Returns the type of the inventory name
+Returns the type of the inventory item name
</string>
<string name="LSLTipText_llSetPayPrice">
llSetPayPrice(integer price, list quick_pay_buttons)
-Sets the default amount when someone chooses to pay this object.
+Sets the default amount on the dialog that appears when someone chooses to pay this prim
</string>
<string name="LSLTipText_llGetCameraPos">
vector llGetCameraPos()
-Gets current camera position for agent task has permissions for.
+Returns the current camera position for the agent the task has permissions for
</string>
<string name="LSLTipText_llGetCameraRot">
rotation llGetCameraRot()
-Gets current camera orientation for agent task has permissions for.
+Returns the current camera orientation for the agent the task has permissions for
</string>
<string name="LSLTipText_llSetPrimURL">
llSetPrimURL(string url)
-Updates the URL for the web page shown on the sides of the object.
+Updates the URL for the web page shown on the sides of the object
</string>
<string name="LSLTipText_llRefreshPrimURL">
llRefreshPrimURL()
-Reloads the web page shown on the sides of the object.
+Reloads the web page shown on the sides of the object
</string>
<string name="LSLTipText_llEscapeURL">
string llEscapeURL(string url)
-Returns and escaped/encoded version of url, replacing spaces with %20 etc.
+Returns an escaped/encoded version of url, replacing spaces with %20 etc.
</string>
<string name="LSLTipText_llUnescapeURL">
string llUnescapeURL(string url)
-Returns and unescaped/unencoded version of url, replacing %20 with spaces etc.
+Returns an unescaped/ unencoded version of url, replacing %20 with spaces etc.
</string>
<string name="LSLTipText_llMapDestination">
llMapDestination(string simname, vector pos, vector look_at)
-Opens world map centered on region with pos highlighted.
+Opens the World Map centered on the region simname with pos highlighted. (NOTE: look_at currently does nothing.)
Only works for scripts attached to avatar, or during touch events.
-(NOTE: look_at currently does nothing)
</string>
<string name="LSLTipText_llAddToLandBanList">
llAddToLandBanList(key avatar, float hours)
-Add avatar to the land ban list for hours
+Adds avatar to the land ban list for hours, or indefinitely if hours is 0
</string>
<string name="LSLTipText_llRemoveFromLandPassList">
llRemoveFromLandPassList(key avatar)
-Remove avatar from the land pass list
+Removes avatar from the land pass list
</string>
<string name="LSLTipText_llRemoveFromLandBanList">
llRemoveFromLandBanList(key avatar)
-Remove avatar from the land ban list
+Removes avatar from the land ban list
</string>
<string name="LSLTipText_llSetCameraParams">
llSetCameraParams(list rules)
@@ -1585,158 +1582,174 @@ List format is [ rule1, data1, rule2, data2 . . . rulen, datan ]
</string>
<string name="LSLTipText_llClearCameraParams">
llClearCameraParams()
-Resets all camera parameters to default values and turns off scripted camera control.
+Resets all camera parameters to default values and turns off scripted camera control
</string>
<string name="LSLTipText_llListStatistics">
-float llListStatistics(integer operation, list l)
-Perform statistical aggregate functions on list l using LIST_STAT_* operations.
+float llListStatistics(integer operation, list src)
+Performs statistical aggregate functions on list src using LIST_STAT_* operations
</string>
<string name="LSLTipText_llGetUnixTime">
integer llGetUnixTime()
-Get the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock.
+Returns the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock
</string>
<string name="LSLTipText_llGetParcelFlags">
integer llGetParcelFlags(vector pos)
-Get the parcel flags (PARCEL_FLAG_*) for the parcel including the point pos.
+Returns a mask of the parcel flags (PARCEL_FLAG_*) for the parcel that includes the point pos
</string>
<string name="LSLTipText_llGetRegionFlags">
integer llGetRegionFlags()
-Get the region flags (REGION_FLAG_*) for the region the object is in.
+Returns the region flags (REGION_FLAG_*) for the region the object is in
</string>
<string name="LSLTipText_llXorBase64StringsCorrect">
string llXorBase64StringsCorrect(string s1, string s2)
-Correctly performs an exclusive or on two Base 64 strings and returns a Base 64 string. s2 repeats if it is shorter than s1.
+Correctly performs an exclusive or on two Base64 strings and returns a Base64 string.
+s2 repeats if it is shorter than s1.
</string>
<string name="LSLTipText_llHTTPRequest">
llHTTPRequest(string url, list parameters, string body)
-Send an HTTP request.
+Sends an HTTP request to the specified url with the body of the request and parameters
</string>
<string name="LSLTipText_llResetLandBanList">
llResetLandBanList()
-Removes all residents from the land ban list.
+Removes all residents from the land ban list
</string>
<string name="LSLTipText_llResetLandPassList">
llResetLandPassList()
-Removes all residents from the land access/pass list.
+Removes all residents from the land access/pass list
</string>
<string name="LSLTipText_llGetObjectPrimCount">
integer llGetObjectPrimCount(key object_id)
-Returns the total number of prims for an object.
+Returns the total number of prims for an object in the region
</string>
<string name="LSLTipText_llGetParcelPrimOwners">
list llGetParcelPrimOwners(vector pos)
-Returns a list of all residents who own objects on the parcel and the number of objects they own.
+Returns a list of all residents who own objects on the parcel at pos and with individual prim counts.
Requires owner-like permissions for the parcel.
</string>
<string name="LSLTipText_llGetParcelPrimCount">
integer llGetParcelPrimCount(vector pos, integer category, integer sim_wide)
-Gets the number of prims on the parcel of the given category.
-Categories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP.
+Returns the number of prims on the parcel at pos of the given category.
+Categories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP
</string>
<string name="LSLTipText_llGetParcelMaxPrims">
integer llGetParcelMaxPrims(vector pos, integer sim_wide)
-Gets the maximum number of prims allowed on the parcel at pos.
+Returns the maximum number of prims allowed on the parcel at pos
</string>
<string name="LSLTipText_llGetParcelDetails">
list llGetParcelDetails(vector pos, list params)
-Gets the parcel details specified in params for the parcel at pos.
+Returns the parcel details specified in params for the parcel at pos.
Params is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA
</string>
<string name="LSLTipText_llSetLinkPrimitiveParams">
llSetLinkPrimitiveParams(integer linknumber, list rules)
-Set primitive parameters for linknumber based on rules.
+Sets primitive parameters for linknumber based on rules
</string>
<string name="LSLTipText_llSetLinkTexture">
-llSetLinkTexture(integer link_pos, string texture, integer face)
-Sets the texture of face for link_pos
+llSetLinkTexture(integer linknumber, string texture, integer face)
+Sets the texture of face for a task that exists in the link chain at linknumber
</string>
<string name="LSLTipText_llStringTrim">
string llStringTrim(string src, integer trim_type)
-Trim leading and/or trailing spaces from a string.
-Uses trim_type of STRING_TRIM, STRING_TRIM_HEAD or STRING_TRIM_TAIL.
+Trims the leading and/or trailing white spaces from a string.
+trim_type can be STRING_TRIM, STRING_TRIM_HEAD or STRING_TRIM_TAIL.
</string>
<string name="LSLTipText_llRegionSay">
llRegionSay(integer channel, string msg)
-broadcasts msg to entire region on channel (not 0.)
+Broadcasts msg on channel (not 0) that can be heard anywhere in the region by a script listening on channel
</string>
<string name="LSLTipText_llGetObjectDetails">
list llGetObjectDetails(key id, list params)
-Gets the object details specified in params for the object with key id.
-Details are OBJECT_NAME, _DESC, _POS, _ROT, _VELOCITY, _OWNER, _GROUP, _CREATOR.
+Returns the object details specified in params for the object with key id.
+Params are OBJECT_NAME, _DESC, _POS, _ROT, _VELOCITY, _OWNER, _GROUP, _CREATOR
</string>
<string name="LSLTipText_llSetClickAction">
llSetClickAction(integer action)
-Sets the action performed when a prim is clicked upon.
+Sets the action performed when a prim is clicked upon
</string>
<string name="LSLTipText_llGetRegionAgentCount">
-int llGetRegionAgentCount()
-returns the number of agents in a region
+integer llGetRegionAgentCount()
+Returns the number of avatars in the region
</string>
<string name="LSLTipText_llTextBox">
llTextBox(key avatar, string message, integer chat_channel
-Shows a dialog box on the avatar's screen with the message.
-A text box asks for input, and if entered the text is chatted on chat_channel.
+Shows a dialog box on the avatar&apos;s screen with the message.
+It contains a text box for input, and if entered that text is chatted on chat_channel.
</string>
<string name="LSLTipText_llGetAgentLanguage">
-string llGetAgentLanguage(key id)
-Gets the agents preferred language..
+string llGetAgentLanguage(key avatar)
+Returns the language code of the preferred interface language of the avatar
</string>
<string name="LSLTipText_llDetectedTouchUV">
-vector llDetectedTouchUV(integer number)
-returns the u and v coordinates in the first two components of a vector, for a triggered touch event
+vector llDetectedTouchUV(integer index)
+Returns the u and v coordinates in the first two components of a vector, for the texture coordinates where the prim was touched in a triggered touch event
</string>
<string name="LSLTipText_llDetectedTouchFace">
-integer llDetectedTouchFace(integer number)
-returns the index of the face on the object for a triggered touch event
+integer llDetectedTouchFace(integer index)
+Returns the index of the face where the avatar clicked in a triggered touch event
</string>
<string name="LSLTipText_llDetectedTouchPos">
-vector llDetectedTouchPos(integer number)
-returns the position touched for a triggered touch event
+vector llDetectedTouchPos(integer index)
+Returns the position where the object was touched in a triggered touch event
</string>
<string name="LSLTipText_llDetectedTouchNormal">
-vector llDetectedTouchNormal(integer number)
-returns the surface normal for a triggered touch event
+vector llDetectedTouchNormal(integer index)
+Returns the surface normal for a triggered touch event
</string>
<string name="LSLTipText_llDetectedTouchBinormal">
-vector llDetectedTouchBinormal(integer number)
-returns the surface binormal for a triggered touch event
+vector llDetectedTouchBinormal(integer index)
+Returns the surface binormal for a triggered touch event
</string>
<string name="LSLTipText_llDetectedTouchST">
-vector llDetectedTouchST(integer number)
-returns the s and t coordinates in the first two components of a vector, for a triggered touch event
+vector llDetectedTouchST(integer index)
+Returns the s and t coordinates in the first two components of a vector, for the surface coordinates where the prim was touched in a triggered touch event
</string>
<string name="LSLTipText_llSHA1String">
-string llSHA1String(string sr)
-Performs a SHA1 security Hash. Returns a 40 character hex string.
+string llSHA1String(string src)
+Returns a string of 40 hex characters that is the SHA1 security Hash of src
</string>
<string name="LSLTipText_llGetFreeURLs">
integer llGetFreeURLs()
-returns the available urls for the current script
+Returns the number of available URLs for the current script
</string>
<string name="LSLTipText_llRequestURL">
key llRequestURL()
-Requests one HTTP:// url for use by this object
-Triggers an http_server event with results.
+Requests one HTTP:// url for use by this object.
+An http_request event is triggered with the results.
</string>
<string name="LSLTipText_llRequestSecureURL">
key llRequestSecureURL()
-Requests one HTTPS:// (SSL) url for use by this object
-Triggers an http_server event with results.
+Requests one HTTPS:// (SSL) url for use by this object.
+An http_request event is triggered with the results.
</string>
<string name="LSLTipText_llReleaseURL">
llReleaseURL(string url)
-Releases the specified URL, it will no longer be usable.
+Releases the specified URL, it will no longer be usable
</string>
<string name="LSLTipText_llHTTPResponse">
-llHTTPResponse(key id, integer status, string body)
-Responds to request id with status and body.
- </string>
+llHTTPResponse(key request_id, integer status, string body)
+Responds to request_id with status and body
+ </string>
<string name="LSLTipText_llGetHTTPHeader">
-string llGetHTTPHeader(key id, string header)
-Get the value for header for request id.
- </string>
-
- <!-- Avatar busy/away mode -->
+string llGetHTTPHeader(key request_id, string header)
+Returns the value for header for request_id
+ </string>
+ <string name="LSLTipText_llSetPrimMediaParams">
+llSetPrimMediaParams(integer face, list params)
+Sets the media params for a particular face on an object. If media is not already on this object, add it.
+List is a set of name/value pairs in no particular order. Params not specified are unchanged, or if new media is added then set to the default specified.
+The possible names are below, along with the types of values and what they mean.
+ </string>
+ <string name="LSLTipText_llGetPrimMediaParams">
+list llGetPrimMediaParams(integer face, list params)
+Returns the media params for a particular face on an object, given the desired list of names, in the order requested.
+(Returns an empty list if no media exists on the face.)
+ </string>
+ <string name="LSLTipText_llClearPrimMedia">
+llClearPrimMedia(integer face)
+Clears (deletes) the media and all params from the given face.
+ </string>
+
+ <!-- Avatar busy/away mode -->
<string name="AvatarSetNotAway">Set Not Away</string>
<string name="AvatarSetAway">Set Away</string>
<string name="AvatarSetNotBusy">Set Not Busy</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
index cb876da8d8..824a815a99 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
@@ -10,9 +10,9 @@
highlighted_color="ScrollHighlightedColor"
column_padding="5"
draw_stripes="true"
+ scroll_bar_bg_visible="false"
+ scroll_bar_bg_color="black"
background_visible="false"
heading_height="23"
draw_border="false"
- draw_heading="false"
- scroll_bar_bg_visible="false"
- scroll_bar_bg_color="black" />
+ draw_heading="false" />
diff --git a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
index 6e73e997e0..e998635d20 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
@@ -12,17 +12,20 @@
<combo_editor
select_on_focus="true"
text_pad_left="20"
+ tool_tip="Search"
background_image="TextField_Search_Off"
background_image_disabled="TextField_Search_Disabled"
background_image_focused="TextField_Search_Active"/>
<combo_list
multi_select="false"
- page_lines="10" />
+ page_lines="10"
+ scroll_bar_bg_visible="true" />
<search_button label=""
top_pad="4"
left_pad="4"
width="13"
height="13"
+ tool_tip="Search"
image_unselected="Search"
image_selected="Search" />
</search_combo_box> \ No newline at end of file
diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp
new file mode 100644
index 0000000000..40f7d532bc
--- /dev/null
+++ b/indra/newview/tests/llviewerhelputil_test.cpp
@@ -0,0 +1,127 @@
+/**
+ * @file llviewerhelputil_test.cpp
+ * @brief LLViewerHelpUtil tests
+ * @author Tofu Linden
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "../test/lltut.h"
+
+#include "../llviewerhelputil.h"
+#include "llcontrol.h"
+#include "llsys.h"
+
+#include <iostream>
+
+//----------------------------------------------------------------------------
+// Implementation of enough of LLControlGroup to support the tests:
+
+static std::map<std::string,std::string> test_stringvec;
+
+LLControlGroup::LLControlGroup(const std::string& name)
+ : LLInstanceTracker<LLControlGroup, std::string>(name)
+{
+}
+
+LLControlGroup::~LLControlGroup()
+{
+}
+
+// Implementation of just the LLControlGroup methods we requre
+BOOL LLControlGroup::declareString(const std::string& name,
+ const std::string& initial_val,
+ const std::string& comment,
+ BOOL persist)
+{
+ test_stringvec[name] = initial_val;
+ return true;
+}
+
+void LLControlGroup::setString(const std::string& name, const std::string& val)
+{
+ test_stringvec[name] = val;
+}
+
+std::string LLControlGroup::getString(const std::string& name)
+{
+ return test_stringvec[name];
+}
+
+//----------------------------------------------------------------------------
+
+namespace tut
+{
+ struct viewerhelputil
+ {
+ };
+
+ typedef test_group<viewerhelputil> viewerhelputil_t;
+ typedef viewerhelputil_t::object viewerhelputil_object_t;
+ tut::viewerhelputil_t tut_viewerhelputil("viewerhelputil");
+
+ template<> template<>
+ void viewerhelputil_object_t::test<1>()
+ {
+ LLOSInfo osinfo;
+ LLControlGroup cgr("test");
+ cgr.declareString("HelpURLFormat", "fooformat", "declared_for_test", FALSE);
+ cgr.declareString("VersionChannelName", "foochannelname", "declared_for_test", FALSE);
+ cgr.declareString("Language", "foolanguage", "declared_for_test", FALSE);
+ std::string topic("test_topic");
+
+ std::string subresult;
+
+ cgr.setString("HelpURLFormat", "fooformat");
+ subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+ ensure_equals("no substitution tags", subresult, "fooformat");
+
+ cgr.setString("HelpURLFormat", "");
+ subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+ ensure_equals("blank substitution format", subresult, "");
+
+ cgr.setString("HelpURLFormat", "[LANGUAGE]");
+ cgr.setString("Language", "");
+ subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+ ensure_equals("simple substitution with blank", subresult, "");
+
+ cgr.setString("HelpURLFormat", "[LANGUAGE]");
+ cgr.setString("Language", "Esperanto");
+ subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+ ensure_equals("simple substitution", subresult, "Esperanto");
+
+ cgr.setString("HelpURLFormat", "[XXX]");
+ subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+ ensure_equals("unknown substitution", subresult, "[XXX]");
+
+ cgr.setString("HelpURLFormat", "[LANGUAGE]/[LANGUAGE]");
+ cgr.setString("Language", "Esperanto");
+ subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+ ensure_equals("multiple substitution", subresult, "Esperanto/Esperanto");
+ }
+
+}
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index e85fddbc99..036fa4923f 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -169,6 +169,12 @@ class WindowsManifest(ViewerManifest):
# the final exe is complicated because we're not sure where it's coming from,
# nor do we have a fixed name for the executable
self.path(self.find_existing_file('debug/secondlife-bin.exe', 'release/secondlife-bin.exe', 'relwithdebinfo/secondlife-bin.exe'), dst=self.final_exe())
+
+ # Plugin host application
+ self.path(os.path.join(os.pardir,
+ 'llplugin', 'slplugin', self.args['configuration'], "slplugin.exe"),
+ "slplugin.exe")
+
# need to get the kdu dll from any of the build directories as well
try:
self.path(self.find_existing_file('../llkdu/%s/llkdu.dll' % self.args['configuration'],
@@ -193,11 +199,6 @@ class WindowsManifest(ViewerManifest):
self.path("openjpeg.dll")
self.end_prefix()
- # Plugin host application
- if self.prefix(src='../llplugin/slplugin/%s' % self.args['configuration'], dst="llplugin"):
- self.path("slplugin.exe")
- self.end_prefix()
-
# Media plugins - QuickTime
if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_quicktime.dll")
@@ -248,10 +249,12 @@ class WindowsManifest(ViewerManifest):
# Vivox runtimes
if self.prefix(src="vivox-runtime/i686-win32", dst=""):
self.path("SLVoice.exe")
- self.path("alut.dll")
+ self.path("libsndfile-1.dll")
+ self.path("zlib1.dll")
self.path("vivoxsdk.dll")
+ self.path("vivoxplatform.dll")
self.path("ortp.dll")
- self.path("wrap_oal.dll")
+ self.path("vivoxoal.dll")
self.end_prefix()
# pull in the crash logger and updater from other projects
@@ -461,10 +464,11 @@ class DarwinManifest(ViewerManifest):
self.path("zh-Hans.lproj")
# SLVoice and vivox lols
- self.path("vivox-runtime/universal-darwin/libalut.dylib", "libalut.dylib")
- self.path("vivox-runtime/universal-darwin/libopenal.dylib", "libopenal.dylib")
+ self.path("vivox-runtime/universal-darwin/libsndfile.dylib", "libsndfile.dylib")
+ self.path("vivox-runtime/universal-darwin/libvivoxoal.dylib", "libvivoxoal.dylib")
self.path("vivox-runtime/universal-darwin/libortp.dylib", "libortp.dylib")
self.path("vivox-runtime/universal-darwin/libvivoxsdk.dylib", "libvivoxsdk.dylib")
+ self.path("vivox-runtime/universal-darwin/libvivoxplatform.dylib", "libvivoxplatform.dylib")
self.path("vivox-runtime/universal-darwin/SLVoice", "SLVoice")
# need to get the kdu dll from any of the build directories as well
@@ -484,9 +488,11 @@ class DarwinManifest(ViewerManifest):
self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
+ # plugin launcher
+ self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
+
# plugins
if self.prefix(src="", dst="llplugin"):
- self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib")
self.path("../../libraries/universal-darwin/lib_release/libllqtwebkit.dylib", "libllqtwebkit.dylib")
@@ -677,6 +683,7 @@ class Linux_i686Manifest(LinuxManifest):
self.path("secondlife-stripped","bin/do-not-directly-run-secondlife-bin")
self.path("../linux_crash_logger/linux-crash-logger-stripped","bin/linux-crash-logger.bin")
self.path("../linux_updater/linux-updater-stripped", "bin/linux-updater.bin")
+ self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin")
if self.prefix("res-sdl"):
self.path("*")
# recurse
@@ -684,7 +691,6 @@ class Linux_i686Manifest(LinuxManifest):
# plugins
if self.prefix(src="", dst="bin/llplugin"):
- self.path("../llplugin/slplugin/SLPlugin", "SLPlugin")
self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_quicktime.so")
self.end_prefix("bin/llplugin")
@@ -715,7 +721,10 @@ class Linux_i686Manifest(LinuxManifest):
self.end_prefix()
if self.prefix(src="vivox-runtime/i686-linux", dst="lib"):
self.path("libortp.so")
+ self.path("libsndfile.so.1")
+ self.path("libvivoxoal.so.1")
self.path("libvivoxsdk.so")
+ self.path("libvivoxplatform.so")
self.end_prefix("lib")
class Linux_x86_64Manifest(LinuxManifest):
diff --git a/install.xml b/install.xml
index 225dc76a9a..0f8b4ac465 100644
--- a/install.xml
+++ b/install.xml
@@ -1334,23 +1334,23 @@ anguage Infrstructure (CLI) international standard</string>
<key>darwin</key>
<map>
<key>md5sum</key>
- <string>8675b5eedef038b514338b17f0e55961</string>
+ <string>3eb4b31e92e16567e2fa967df9f9b845</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6270-darwin-20090309.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.0.0006.7278-darwin-20090930a.tar.bz2</uri>
</map>
<key>linux</key>
<map>
<key>md5sum</key>
- <string>01573510dce7f380f44e561ef2f3dd9f</string>
+ <string>61ab6acd1f4736c5260c492bb60c26af</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6270-linux-20090309.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.0.0006.7278-linux-20090930a.tar.bz2</uri>
</map>
<key>windows</key>
<map>
<key>md5sum</key>
- <string>752daa90e07c05202d1f76980cb955eb</string>
+ <string>ad5737dbfab87a13b23451b68248b22a</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6270-windows-20090309.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.0.0006.7278-windows-20090930a.tar.bz2</uri>
</map>
</map>
</map>