summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/linux_updater/linux_updater.cpp4
-rw-r--r--indra/llcommon/lldate.cpp30
-rw-r--r--indra/llcommon/lldate.h1
-rw-r--r--indra/llcommon/lllslconstants.h13
-rw-r--r--indra/llcommon/llsdserialize_xml.cpp12
-rw-r--r--indra/llcommon/llstringtable.h10
-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.txt6
-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.cpp56
-rw-r--r--indra/llui/lldockablefloater.h23
-rw-r--r--indra/llui/lldockcontrol.cpp176
-rw-r--r--indra/llui/lldockcontrol.h16
-rw-r--r--indra/llui/llflatlistview.cpp199
-rw-r--r--indra/llui/llflatlistview.h142
-rw-r--r--indra/llui/llfloater.cpp129
-rw-r--r--indra/llui/llfloater.h14
-rw-r--r--indra/llui/llfocusmgr.cpp38
-rw-r--r--indra/llui/llfocusmgr.h20
-rw-r--r--indra/llui/llhelp.h45
-rw-r--r--indra/llui/llmultisliderctrl.cpp2
-rw-r--r--indra/llui/llnotifications.cpp2
-rw-r--r--indra/llui/llpanel.cpp3
-rw-r--r--indra/llui/llpanel.h8
-rw-r--r--indra/llui/llscrollbar.cpp13
-rw-r--r--indra/llui/llscrollbar.h8
-rw-r--r--indra/llui/llscrollcontainer.cpp2
-rw-r--r--indra/llui/llscrolllistctrl.cpp6
-rw-r--r--indra/llui/llscrolllistctrl.h6
-rw-r--r--indra/llui/llsliderctrl.cpp2
-rw-r--r--indra/llui/llspinctrl.cpp2
-rw-r--r--indra/llui/lltextbox.h1
-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/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.txt35
-rw-r--r--indra/newview/app_settings/keywords.ini45
-rw-r--r--indra/newview/app_settings/settings.xml150
-rw-r--r--indra/newview/llagentwearables.cpp107
-rw-r--r--indra/newview/llagentwearables.h6
-rw-r--r--indra/newview/llappearancemgr.cpp26
-rw-r--r--indra/newview/llappviewer.cpp6
-rw-r--r--indra/newview/llavataractions.cpp59
-rw-r--r--indra/newview/llavataractions.h16
-rw-r--r--indra/newview/llavatariconctrl.cpp52
-rw-r--r--indra/newview/llavatarlist.cpp546
-rw-r--r--indra/newview/llavatarlist.h110
-rw-r--r--indra/newview/llavatarlistitem.cpp50
-rw-r--r--indra/newview/llavatarlistitem.h18
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp19
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h2
-rw-r--r--indra/newview/llbottomtray.cpp81
-rw-r--r--indra/newview/llbottomtray.h13
-rw-r--r--indra/newview/llcallingcard.cpp6
-rw-r--r--indra/newview/llcallingcard.h3
-rw-r--r--indra/newview/llchannelmanager.cpp148
-rw-r--r--indra/newview/llchannelmanager.h51
-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.cpp86
-rw-r--r--indra/newview/llchiclet.h18
-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/llexpandabletextbox.cpp508
-rw-r--r--indra/newview/llexpandabletextbox.h237
-rw-r--r--indra/newview/llface.cpp22
-rw-r--r--indra/newview/llface.h1
-rw-r--r--indra/newview/llfavoritesbar.cpp136
-rw-r--r--indra/newview/llfavoritesbar.h20
-rw-r--r--indra/newview/llfloaterbuycurrency.cpp42
-rw-r--r--indra/newview/llfloatercamera.cpp91
-rw-r--r--indra/newview/llfloatercamera.h24
-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.cpp8
-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.cpp253
-rw-r--r--indra/newview/llgrouplist.h73
-rw-r--r--indra/newview/llimfloater.cpp421
-rw-r--r--indra/newview/llimfloater.h114
-rw-r--r--indra/newview/llimhandler.cpp73
-rw-r--r--indra/newview/llimpanel.cpp412
-rw-r--r--indra/newview/llimpanel.h73
-rw-r--r--indra/newview/llimview.cpp265
-rw-r--r--indra/newview/llimview.h70
-rw-r--r--indra/newview/llinventorybridge.cpp9
-rw-r--r--indra/newview/lllandmarkactions.cpp44
-rw-r--r--indra/newview/lllandmarkactions.h23
-rw-r--r--indra/newview/lllocationinputctrl.cpp20
-rw-r--r--indra/newview/llmediactrl.cpp173
-rw-r--r--indra/newview/llmediactrl.h20
-rw-r--r--indra/newview/llmoveview.cpp95
-rw-r--r--indra/newview/llmoveview.h12
-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.cpp32
-rw-r--r--indra/newview/llnearbychatbar.h2
-rw-r--r--indra/newview/llnearbychathandler.cpp276
-rw-r--r--indra/newview/llnearbychathandler.h6
-rw-r--r--indra/newview/llnotificationalerthandler.cpp68
-rw-r--r--indra/newview/llnotificationgrouphandler.cpp82
-rw-r--r--indra/newview/llnotificationhandler.h117
-rw-r--r--indra/newview/llnotificationmanager.cpp26
-rw-r--r--indra/newview/llnotificationmanager.h6
-rw-r--r--indra/newview/llnotificationscripthandler.cpp142
-rw-r--r--indra/newview/llnotificationtiphandler.cpp114
-rw-r--r--indra/newview/lloutputmonitorctrl.cpp2
-rw-r--r--indra/newview/llpanelavatar.cpp5
-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.cpp167
-rw-r--r--indra/newview/llpanelgroup.h8
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp64
-rw-r--r--indra/newview/llpanelgroupgeneral.h1
-rw-r--r--indra/newview/llpanelgrouproles.cpp2
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp3
-rw-r--r--indra/newview/llpanellandmedia.cpp11
-rw-r--r--indra/newview/llpanellandmedia.h9
-rw-r--r--indra/newview/llpanellogin.cpp27
-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.cpp417
-rw-r--r--indra/newview/llpanelpeople.h34
-rw-r--r--indra/newview/llpanelpeoplemenus.cpp148
-rw-r--r--indra/newview/llpanelpeoplemenus.h82
-rw-r--r--indra/newview/llpanelpick.cpp165
-rw-r--r--indra/newview/llpanelpick.h26
-rw-r--r--indra/newview/llpanelpicks.cpp25
-rw-r--r--indra/newview/llpanelpicks.h9
-rw-r--r--indra/newview/llpanelplaceinfo.cpp81
-rw-r--r--indra/newview/llpanelplaceinfo.h8
-rw-r--r--indra/newview/llpanelplaces.cpp99
-rw-r--r--indra/newview/llpanelplaces.h3
-rw-r--r--indra/newview/llpanelprofile.cpp9
-rw-r--r--indra/newview/llpanelprofile.h7
-rw-r--r--indra/newview/llpanelprofileview.cpp21
-rw-r--r--indra/newview/llpanelprofileview.h10
-rw-r--r--indra/newview/llpanelteleporthistory.cpp401
-rw-r--r--indra/newview/llpanelteleporthistory.h43
-rw-r--r--indra/newview/llpreviewscript.cpp104
-rw-r--r--indra/newview/llpreviewscript.h4
-rw-r--r--indra/newview/llrecentpeople.cpp19
-rw-r--r--indra/newview/llrecentpeople.h4
-rw-r--r--indra/newview/llremoteparcelrequest.cpp3
-rw-r--r--indra/newview/llscreenchannel.cpp211
-rw-r--r--indra/newview/llscreenchannel.h180
-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.cpp57
-rw-r--r--indra/newview/llstatusbar.h7
-rw-r--r--indra/newview/llsyswellitem.cpp11
-rw-r--r--indra/newview/llsyswellitem.h6
-rw-r--r--indra/newview/llsyswellwindow.cpp430
-rw-r--r--indra/newview/llsyswellwindow.h55
-rw-r--r--indra/newview/lltoast.cpp82
-rw-r--r--indra/newview/lltoast.h48
-rw-r--r--indra/newview/lltoastimpanel.cpp15
-rw-r--r--indra/newview/lltoastimpanel.h2
-rw-r--r--indra/newview/lltoastnotifypanel.cpp1
-rw-r--r--indra/newview/lltoastpanel.h6
-rw-r--r--indra/newview/lltool.cpp16
-rw-r--r--indra/newview/lltooldraganddrop.cpp2
-rw-r--r--indra/newview/lltooldraganddrop.h6
-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/llviewercontrol.cpp37
-rw-r--r--indra/newview/llviewerfloaterreg.cpp15
-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.cpp44
-rw-r--r--indra/newview/llviewermenu.h1
-rw-r--r--indra/newview/llviewermessage.cpp1
-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.cpp39
-rw-r--r--indra/newview/llviewerwindow.h5
-rw-r--r--indra/newview/llvoiceclient.cpp1
-rw-r--r--indra/newview/llvoiceclient.h2
-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/icons/Generic_Group.pngbin550 -> 3354 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Generic_Person.pngbin451 -> 3280 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml20
-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/da/floater_about.xml14
-rw-r--r--indra/newview/skins/default/xui/da/floater_map.xml102
-rw-r--r--indra/newview/skins/default/xui/da/panel_preferences_advanced.xml24
-rw-r--r--indra/newview/skins/default/xui/da/panel_world_map.xml102
-rw-r--r--indra/newview/skins/default/xui/de/floater_about.xml14
-rw-r--r--indra/newview/skins/default/xui/de/floater_map.xml102
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_advanced.xml24
-rw-r--r--indra/newview/skins/default/xui/de/panel_world_map.xml102
-rw-r--r--indra/newview/skins/default/xui/en/accordion_parent.xml2
-rw-r--r--indra/newview/skins/default/xui/en/favorites_bar_button.xml10
-rw-r--r--indra/newview/skins/default/xui/en/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_bulk_perms.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_currency.xml331
-rw-r--r--indra/newview/skins/default/xui/en/floater_camera.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_help_browser.xml165
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_lagmeter.xml30
-rw-r--r--indra/newview/skins/default/xui/en/floater_media_settings.xml20
-rw-r--r--indra/newview/skins/default/xui/en/floater_moveview.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_mute_object.xml49
-rw-r--r--indra/newview/skins/default/xui/en/floater_sys_well.xml45
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml249
-rw-r--r--indra/newview/skins/default/xui/en/floater_ui_preview.xml18
-rw-r--r--indra/newview/skins/default/xui/en/floater_whitelist_entry.xml24
-rw-r--r--indra/newview/skins/default/xui/en/menu_bottomtray.xml44
-rw-r--r--indra/newview/skins/default/xui/en/menu_hide_navbar.xml20
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml16
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_nearby.xml65
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml4
-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.xml56
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml113
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml63
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml46
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_list_item.xml66
-rw-r--r--indra/newview/skins/default/xui/en/panel_instant_message.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml49
-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_navigation_bar.xml1
-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_people.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_list_item.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml18
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml82
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile.xml20
-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.xml14
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_sys_well_item.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history.xml122
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history_item.xml65
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml799
-rw-r--r--indra/newview/skins/default/xui/en/widgets/accordion_tab.xml10
-rw-r--r--indra/newview/skins/default/xui/en/widgets/expandable_text.xml27
-rw-r--r--indra/newview/skins/default/xui/en/widgets/filter_editor.xml8
-rw-r--r--indra/newview/skins/default/xui/en/widgets/flat_list_view.xml3
-rw-r--r--indra/newview/skins/default/xui/en/widgets/list.xml10
-rw-r--r--indra/newview/skins/default/xui/en/widgets/location_input.xml3
-rw-r--r--indra/newview/skins/default/xui/en/widgets/scroll_list.xml10
-rw-r--r--indra/newview/skins/default/xui/en/widgets/search_combo_box.xml5
-rw-r--r--indra/newview/skins/default/xui/es/floater_about.xml14
-rw-r--r--indra/newview/skins/default/xui/es/floater_map.xml102
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_advanced.xml24
-rw-r--r--indra/newview/skins/default/xui/es/panel_world_map.xml102
-rw-r--r--indra/newview/skins/default/xui/fr/floater_about.xml14
-rw-r--r--indra/newview/skins/default/xui/fr/floater_map.xml102
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml24
-rw-r--r--indra/newview/skins/default/xui/fr/panel_world_map.xml102
-rw-r--r--indra/newview/skins/default/xui/it/floater_about.xml14
-rw-r--r--indra/newview/skins/default/xui/it/floater_map.xml102
-rw-r--r--indra/newview/skins/default/xui/it/panel_preferences_advanced.xml24
-rw-r--r--indra/newview/skins/default/xui/it/panel_world_map.xml102
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about.xml14
-rw-r--r--indra/newview/skins/default/xui/ja/floater_map.xml102
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml24
-rw-r--r--indra/newview/skins/default/xui/ja/panel_world_map.xml102
-rw-r--r--indra/newview/skins/default/xui/nl/floater_about.xml13
-rw-r--r--indra/newview/skins/default/xui/nl/floater_map.xml102
-rw-r--r--indra/newview/skins/default/xui/nl/panel_world_map.xml102
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_about.xml15
-rw-r--r--indra/newview/skins/default/xui/pl/floater_map.xml102
-rw-r--r--indra/newview/skins/default/xui/pl/panel_preferences_advanced.xml24
-rw-r--r--indra/newview/skins/default/xui/pl/panel_world_map.xml102
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about.xml13
-rw-r--r--indra/newview/skins/default/xui/pt/floater_map.xml102
-rw-r--r--indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml24
-rw-r--r--indra/newview/skins/default/xui/pt/panel_world_map.xml102
-rw-r--r--indra/newview/tests/llviewerhelputil_test.cpp127
-rwxr-xr-xindra/newview/viewer_manifest.py15
362 files changed, 16997 insertions, 6522 deletions
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/lldate.cpp b/indra/llcommon/lldate.cpp
index 7c0ac6c554..ca7e471bf2 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -254,6 +254,36 @@ bool LLDate::fromStream(std::istream& s)
return true;
}
+bool LLDate::fromYMDHMS(S32 year, S32 month, S32 day, S32 hour, S32 min, S32 sec)
+{
+ struct apr_time_exp_t exp_time;
+
+ exp_time.tm_year = year - 1900;
+ exp_time.tm_mon = month - 1;
+ exp_time.tm_mday = day;
+ exp_time.tm_hour = hour;
+ exp_time.tm_min = min;
+ exp_time.tm_sec = sec;
+
+ // zero out the unused fields
+ exp_time.tm_usec = 0;
+ exp_time.tm_wday = 0;
+ exp_time.tm_yday = 0;
+ exp_time.tm_isdst = 0;
+ exp_time.tm_gmtoff = 0;
+
+ // generate a time_t from that
+ apr_time_t time;
+ if (apr_time_exp_gmt_get(&time, &exp_time) != APR_SUCCESS)
+ {
+ return false;
+ }
+
+ mSecondsSinceEpoch = time / LL_APR_USEC_PER_SEC;
+
+ return true;
+}
+
F64 LLDate::secondsSinceEpoch() const
{
return mSecondsSinceEpoch;
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index 1f14093390..5b1ec9295f 100644
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
@@ -101,6 +101,7 @@ public:
*/
bool fromString(const std::string& iso8601_date);
bool fromStream(std::istream&);
+ bool fromYMDHMS(S32 year, S32 month = 1, S32 day = 0, S32 hour = 0, S32 min = 0, S32 sec = 0);
/**
* @brief Return the date in seconds since epoch.
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/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index c12ca350de..7e1c2e35e0 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -37,6 +37,7 @@
#include <deque>
#include "apr_base64.h"
+#include <boost/regex.hpp>
extern "C"
{
@@ -777,10 +778,17 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)
case ELEMENT_BINARY:
{
- S32 len = apr_base64_decode_len(mCurrentContent.c_str());
+ // Regex is expensive, but only fix for whitespace in base64,
+ // created by python and other non-linden systems - DEV-39358
+ // Fortunately we have very little binary passing now,
+ // so performance impact shold be negligible. + poppy 2009-09-04
+ boost::regex r;
+ r.assign("\\s");
+ std::string stripped = boost::regex_replace(mCurrentContent, r, "");
+ S32 len = apr_base64_decode_len(stripped.c_str());
std::vector<U8> data;
data.resize(len);
- len = apr_base64_decode_binary(&data[0], mCurrentContent.c_str());
+ len = apr_base64_decode_binary(&data[0], stripped.c_str());
data.resize(len);
value = data;
break;
diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h
index b13b016396..ec61ea1982 100644
--- a/indra/llcommon/llstringtable.h
+++ b/indra/llcommon/llstringtable.h
@@ -48,10 +48,12 @@
//# define STRING_TABLE_HASH_MAP 1
#endif
-#if LL_WINDOWS
-#include <hash_map>
-#else
-#include <ext/hash_map>
+#if STRING_TABLE_HASH_MAP
+# if LL_WINDOWS
+# include <hash_map>
+# else
+# include <ext/hash_map>
+# endif
#endif
const U32 MAX_STRINGS_LENGTH = 256;
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 293dea6fe1..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)address;
- U32 address_hi = (U32)(U64(address) / (U64(1)<<31));
- 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 2a8b557f43..5ad758072c 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 2736d54cc8..2c587554a2 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_math.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 65ccb655dd..9d1b59cf66 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -51,7 +51,6 @@ set(llui_SOURCE_FILES
llkeywords.cpp
lllayoutstack.cpp
lllineeditor.cpp
- lllistctrl.cpp
lllocalcliprect.cpp
llmenugl.cpp
llmodaldialog.cpp
@@ -88,6 +87,7 @@ set(llui_SOURCE_FILES
lltextbox.cpp
lltexteditor.cpp
lltextparser.cpp
+ lltransientfloatermgr.cpp
lltransutil.cpp
lltooltip.cpp
llui.cpp
@@ -133,13 +133,12 @@ set(llui_HEADER_FILES
llfocusmgr.h
llfunctorregistry.h
llhandle.h
- llhtmlhelp.h
+ llhelp.h
lliconctrl.h
llkeywords.h
lllayoutstack.h
lllazyvalue.h
lllineeditor.h
- lllistctrl.h
lllocalcliprect.h
llmenugl.h
llmodaldialog.h
@@ -177,6 +176,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 ed15d9d922..4525f0a45b 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -35,12 +35,21 @@
#include "lldockablefloater.h"
//static
-LLHandle<LLFloater> LLDockableFloater::instanceHandle;
+LLHandle<LLFloater> LLDockableFloater::sInstanceHandle;
LLDockableFloater::LLDockableFloater(LLDockControl* dockControl,
const LLSD& key, const Params& params) :
- LLFloater(key, params), mDockControl(dockControl)
+ LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(true)
{
+ setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible());
+ resetInstance();
+}
+
+LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, bool uniqueDocking,
+ const LLSD& key, const Params& params) :
+ LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(uniqueDocking)
+{
+ setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible());
resetInstance();
}
@@ -57,21 +66,13 @@ BOOL LLDockableFloater::postBuild()
void LLDockableFloater::resetInstance()
{
- if (instanceHandle.get() != this)
+ if (mUniqueDocking && sInstanceHandle.get() != this)
{
- if (instanceHandle.get() != NULL && instanceHandle.get()->isDocked())
+ if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked())
{
- //closeFloater() is not virtual
- if (instanceHandle.get()->canClose())
- {
- instanceHandle.get()->closeFloater();
- }
- else
- {
- instanceHandle.get()->setVisible(FALSE);
- }
+ sInstanceHandle.get()->setVisible(FALSE);
}
- instanceHandle = getHandle();
+ sInstanceHandle = getHandle();
}
}
@@ -81,12 +82,18 @@ void LLDockableFloater::setVisible(BOOL visible)
{
resetInstance();
}
+
+ if (visible && mDockControl.get() != NULL)
+ {
+ mDockControl.get()->repositionDockable();
+ }
+
LLFloater::setVisible(visible);
}
void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
{
- if (mDockControl.get() != NULL)
+ if (mDockControl.get() != NULL && mDockControl.get()->isDockVisible())
{
if (docked)
{
@@ -97,12 +104,16 @@ void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
{
mDockControl.get()->off();
}
- }
- if (!docked && pop_on_undock)
+ if (!docked && pop_on_undock)
+ {
+ // visually pop up a little bit to emphasize the undocking
+ translate(0, UNDOCK_LEAP_HEIGHT);
+ }
+ }
+ else
{
- // visually pop up a little bit to emphasize the undocking
- translate(0, UNDOCK_LEAP_HEIGHT);
+ docked = false;
}
LLFloater::setDocked(docked, pop_on_undock);
@@ -113,7 +124,10 @@ void LLDockableFloater::draw()
if (mDockControl.get() != NULL)
{
mDockControl.get()->repositionDockable();
- mDockControl.get()->drawToungue();
+ if (isDocked())
+ {
+ mDockControl.get()->drawToungue();
+ }
}
LLFloater::draw();
}
@@ -121,7 +135,9 @@ void LLDockableFloater::draw()
void LLDockableFloater::setDockControl(LLDockControl* dockControl)
{
mDockControl.reset(dockControl);
+ setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible());
}
+
const LLUIImagePtr& LLDockableFloater::getDockTongue()
{
return mDockTongue;
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h
index 1d0e89cef5..ed90567ad3 100644
--- a/indra/llui/lldockablefloater.h
+++ b/indra/llui/lldockablefloater.h
@@ -46,12 +46,26 @@ class LLDockableFloater : public LLFloater
static const U32 UNDOCK_LEAP_HEIGHT = 12;
public:
LOG_CLASS(LLDockableFloater);
- LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params = getDefaultParams());
+ LLDockableFloater(LLDockControl* dockControl, const LLSD& key,
+ const Params& params = getDefaultParams());
+ LLDockableFloater(LLDockControl* dockControl, bool uniqueDocking,
+ const LLSD& key, const Params& params = getDefaultParams());
virtual ~LLDockableFloater();
+ static LLHandle<LLFloater> getInstanceHandle() { return sInstanceHandle; }
+
+ /**
+ * If descendant class overrides postBuild() in order to perform specific
+ * construction then it must still invoke its superclass' implementation.
+ */
/* virtula */BOOL postBuild();
/* virtual */void setDocked(bool docked, bool pop_on_undock = true);
/* virtual */void draw();
+
+ /**
+ * If descendant class overrides setVisible() then it must still invoke its
+ * superclass' implementation.
+ */
/*virtual*/ void setVisible(BOOL visible);
private:
@@ -69,7 +83,12 @@ protected:
private:
std::auto_ptr<LLDockControl> mDockControl;
LLUIImagePtr mDockTongue;
- static LLHandle<LLFloater> instanceHandle;
+ static LLHandle<LLFloater> sInstanceHandle;
+ /**
+ * Provides possibility to define that dockable floaters can be docked
+ * non exclusively.
+ */
+ bool mUniqueDocking;
};
#endif /* LL_DOCKABLEFLOATER_H */
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index d666f2be56..146c7a969a 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -35,12 +35,12 @@
#include "lldockcontrol.h"
LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
- const LLUIImagePtr& dockTongue, DocAt dockAt, bool enabled) :
- mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(
- dockTongue)
+ const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
+ mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue)
{
mDockAt = dockAt;
- if (enabled)
+
+ if (dockableFloater->isDocked())
{
on();
}
@@ -49,7 +49,17 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
off();
}
- if (dockWidget != NULL) {
+ if (!(get_allowed_rect_callback))
+ {
+ mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
+ }
+ else
+ {
+ mGetAllowedRectCallback = get_allowed_rect_callback;
+ }
+
+ if (dockWidget != NULL)
+ {
repositionDockable();
}
}
@@ -67,65 +77,140 @@ void LLDockControl::setDock(LLView* dockWidget)
}
}
+void LLDockControl::getAllowedRect(LLRect& rect)
+{
+ rect = mDockableFloater->getRootView()->getRect();
+}
+
void LLDockControl::repositionDockable()
{
- if (mEnabled)
+ LLRect dockRect = mDockWidget->calcScreenRect();
+ LLRect rootRect;
+ mGetAllowedRectCallback(rootRect);
+ static BOOL prev_visibility = !mDockWidget->getVisible();
+
+ // recalculate dockable position if dock position changed, dock visibility changed,
+ // root view rect changed or recalculation is forced
+ if (mEnabled && (mPrevDockRect != dockRect || prev_visibility != mDockWidget->getVisible()
+ || mRootRect != rootRect || mRecalculateDocablePosition))
{
- calculateDockablePosition();
+ // undock dockable and off() if dock not visible
+ if (!isDockVisible())
+ {
+ mDockableFloater->setDocked(false);
+ // force off() since dockable may not have dockControll at this time
+ off();
+ }
+ else
+ {
+ moveDockable();
+ }
+
+ mPrevDockRect = dockRect;
+ mRootRect = rootRect;
+ mRecalculateDocablePosition = false;
+ prev_visibility = mDockWidget->getVisible();
}
}
-void LLDockControl::calculateDockablePosition()
+bool LLDockControl::isDockVisible()
{
- LLRect dockRect = mDockWidget->calcScreenRect();
- LLRect rootRect = mDockableFloater->getRootView()->getRect();
+ bool res = true;
- // recalculate dockable position if dock position changed
- // or root view rect changed or recalculation is forced
- if (mPrevDockRect != dockRect || mRootRect != rootRect
- || mRecalculateDocablePosition)
+ if (mDockWidget != NULL)
{
- LLRect dockableRect = mDockableFloater->calcScreenRect();
- S32 x = 0;
- S32 y = 0;
- switch (mDockAt)
+ //we should check all hierarchy
+ res = mDockWidget->isInVisibleChain();
+ if (res)
{
- case TOP:
- x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
- y = dockRect.mTop + mDockTongue->getHeight()
- + dockableRect.getHeight();
- if (x < rootRect.mLeft)
- {
- x = rootRect.mLeft;
- }
- if (x + dockableRect.getWidth() > rootRect.mRight)
+ LLRect dockRect = mDockWidget->calcScreenRect();
+
+ switch (mDockAt)
{
- x = rootRect.mRight - dockableRect.getWidth();
+ case TOP:
+ // check is dock inside parent rect
+ LLRect dockParentRect =
+ mDockWidget->getParent()->calcScreenRect();
+ if (dockRect.mRight <= dockParentRect.mLeft
+ || dockRect.mLeft >= dockParentRect.mRight)
+ {
+ res = false;
+ }
+ break;
}
+ }
+ }
+
+ return res;
+}
+
+void LLDockControl::moveDockable()
+{
+ // calculate new dockable position
+ LLRect dockRect = mDockWidget->calcScreenRect();
+ LLRect rootRect;
+ mGetAllowedRectCallback(rootRect);
+
+ 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();
+ }
+
+
+ // calculate dock tongue position
+ LLRect dockParentRect =
+ mDockWidget->getParent()->calcScreenRect();
+ if (dockRect.getCenterX() < dockParentRect.mLeft)
+ {
+ mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
+ }
+ else if (dockRect.getCenterX() > dockParentRect.mRight)
+ {
+ mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
+ }
+ else
+ {
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
- mDockTongueY = dockRect.mTop;
- break;
}
- dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
- dockableRect.getHeight());
- LLRect localDocableParentRect;
- mDockableFloater->getParent()->screenRectToLocal(dockableRect,
- &localDocableParentRect);
- mDockableFloater->setRect(localDocableParentRect);
-
- mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
- &mDockTongueX, &mDockTongueY);
- mPrevDockRect = dockRect;
- mRootRect = rootRect;
- mRecalculateDocablePosition = false;
+ mDockTongueY = dockRect.mTop;
+
+ break;
}
+
+ // move dockable
+ dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+ dockableRect.getHeight());
+ LLRect localDocableParentRect;
+ mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+ &localDocableParentRect);
+ mDockableFloater->setRect(localDocableParentRect);
+
+ mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+ &mDockTongueX, &mDockTongueY);
+
}
void LLDockControl::on()
{
- mDockableFloater->setCanDrag(false);
- mEnabled = true;
- mRecalculateDocablePosition = true;
+ if (isDockVisible())
+ {
+ mDockableFloater->setCanDrag(false);
+ mEnabled = true;
+ mRecalculateDocablePosition = true;
+ }
}
void LLDockControl::off()
@@ -141,3 +226,4 @@ void LLDockControl::drawToungue()
mDockTongue->draw(mDockTongueX, mDockTongueY);
}
}
+
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index 7d8d5c7653..e8ffcac0ac 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -51,10 +51,12 @@ public:
};
public:
+ // callback for a function getting a rect valid for control's position
+ typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t;
+
LOG_CLASS(LLDockControl);
LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
- const LLUIImagePtr& dockTongue, DocAt dockAt,
- bool enabled);
+ const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL);
virtual ~LLDockControl();
public:
@@ -63,9 +65,15 @@ public:
void setDock(LLView* dockWidget);
void repositionDockable();
void drawToungue();
-protected:
- virtual void calculateDockablePosition();
+ bool isDockVisible();
+
+ // gets a rect that bounds possible positions for a dockable control (EXT-1111)
+ void getAllowedRect(LLRect& rect);
+
+private:
+ virtual void moveDockable();
private:
+ 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 75334acb39..e9df361472 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -33,13 +33,16 @@
#include "linden_common.h"
#include "llpanel.h"
+#include "lltextbox.h"
#include "llflatlistview.h"
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";
LLFlatListView::Params::Params()
: item_pad("item_pad"),
@@ -55,7 +58,12 @@ void LLFlatListView::reshape(S32 width, S32 height, BOOL called_from_parent /* =
rearrangeItems();
}
-bool LLFlatListView::addItem(LLPanel* item, LLSD value /* = LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/)
+const LLRect& LLFlatListView::getItemsRect() const
+{
+ return mItemsPanel->getRect();
+}
+
+bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/)
{
if (!item) return false;
if (value.isUndefined()) return false;
@@ -84,11 +92,12 @@ bool LLFlatListView::addItem(LLPanel* item, LLSD value /* = LLUUID::null*/, EAdd
item->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
rearrangeItems();
+ notifyParentItemsRectChanged();
return true;
}
-bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value /*= LLUUID::null*/)
+bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value /*= LLUUID::null*/)
{
if (!after_item) return false;
if (!item_to_add) return false;
@@ -111,11 +120,11 @@ bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add,
else
{
pairs_iterator_t it = mItemPairs.begin();
- ++it;
- while (it != mItemPairs.end())
+ for (; it != mItemPairs.end(); ++it)
{
if (*it == after_pair)
{
+ // insert new elements before the element at position of passed iterator.
mItemPairs.insert(++it, new_pair);
mItemsPanel->addChild(item_to_add);
break;
@@ -128,6 +137,7 @@ bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add,
item_to_add->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
rearrangeItems();
+ notifyParentItemsRectChanged();
return true;
}
@@ -153,14 +163,14 @@ bool LLFlatListView::removeItemByValue(const LLSD& value)
return removeItemPair(item_pair);
}
-bool LLFlatListView::removeItemByUUID(LLUUID& uuid)
+bool LLFlatListView::removeItemByUUID(const LLUUID& uuid)
{
return removeItemByValue(LLSD(uuid));
}
-LLPanel* LLFlatListView::getItemByValue(LLSD& value) const
+LLPanel* LLFlatListView::getItemByValue(const LLSD& value) const
{
- if (value.isDefined()) return NULL;
+ if (value.isUndefined()) return NULL;
item_pair_t* pair = getItemPair(value);
if (pair) return pair->first;
@@ -188,7 +198,7 @@ bool LLFlatListView::selectItemByValue(const LLSD& value, bool select /*= true*/
return selectItemPair(item_pair, select);
}
-bool LLFlatListView::selectItemByUUID(LLUUID& uuid, bool select /* = true*/)
+bool LLFlatListView::selectItemByUUID(const LLUUID& uuid, bool select /* = true*/)
{
return selectItemByValue(LLSD(uuid), select);
}
@@ -252,7 +262,7 @@ void LLFlatListView::getSelectedItems(std::vector<LLPanel*>& selected_items) con
}
}
-void LLFlatListView::resetSelection()
+void LLFlatListView::resetSelection(bool no_commit_on_deselection /*= false*/)
{
if (mSelectedItemPairs.empty()) return;
@@ -264,6 +274,29 @@ void LLFlatListView::resetSelection()
}
mSelectedItemPairs.clear();
+
+ if (mCommitOnSelectionChange && !no_commit_on_deselection)
+ {
+ onCommit();
+ }
+}
+
+void LLFlatListView::setNoItemsCommentText(const std::string& comment_text)
+{
+ if (NULL == mNoItemsCommentTextbox)
+ {
+ LLRect comment_rect = getRect();
+ comment_rect.setOriginAndSize(0, 0, comment_rect.getWidth(), comment_rect.getHeight());
+ comment_rect.stretch(-getBorderWidth());
+ LLTextBox::Params text_p;
+ text_p.name(COMMENT_TEXTBOX);
+ text_p.border_visible(false);
+ text_p.rect(comment_rect);
+ text_p.follows.flags(FOLLOWS_ALL);
+ mNoItemsCommentTextbox = LLUICtrlFactory::create<LLTextBox>(text_p, this);
+ }
+
+ mNoItemsCommentTextbox->setValue(comment_text);
}
void LLFlatListView::clear()
@@ -272,11 +305,32 @@ void LLFlatListView::clear()
for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
{
mItemsPanel->removeChild((*it)->first);
- delete (*it)->first;
+ (*it)->first->die();
delete *it;
}
mItemPairs.clear();
mSelectedItemPairs.clear();
+
+ // also set items panel height to zero. Reshape it to allow reshaping of non-item children
+ LLRect rc = mItemsPanel->getRect();
+ rc.mBottom = rc.mTop;
+ mItemsPanel->reshape(rc.getWidth(), rc.getHeight());
+ mItemsPanel->setRect(rc);
+
+ setNoItemsCommentVisible(true);
+ notifyParentItemsRectChanged();
+}
+
+void LLFlatListView::sort()
+{
+ if (!mItemComparator)
+ {
+ llwarns << "No comparator specified for sorting FlatListView items." << llendl;
+ return;
+ }
+
+ mItemPairs.sort(ComparatorAdaptor(*mItemComparator));
+ rearrangeItems();
}
@@ -286,12 +340,16 @@ void LLFlatListView::clear()
LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
-: LLScrollContainer(p),
- mItemsPanel(NULL),
- mItemPad(p.item_pad),
- mAllowSelection(p.allow_select),
- mMultipleSelection(p.multi_select),
- mKeepOneItemSelected(p.keep_one_selected)
+: LLScrollContainer(p)
+ , mItemComparator(NULL)
+ , mItemsPanel(NULL)
+ , mItemPad(p.item_pad)
+ , mAllowSelection(p.allow_select)
+ , mMultipleSelection(p.multi_select)
+ , mKeepOneItemSelected(p.keep_one_selected)
+ , mCommitOnSelectionChange(false)
+ , mPrevNotifyParentRect(LLRect())
+ , mNoItemsCommentTextbox(NULL)
{
mBorderThickness = getBorderWidth();
@@ -315,19 +373,32 @@ void LLFlatListView::rearrangeItems()
{
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ setNoItemsCommentVisible(mItemPairs.empty());
+
if (mItemPairs.empty()) return;
//calculating required height - assuming items can be of different height
//list should accommodate all its items
S32 height = 0;
+ S32 invisible_children_count = 0;
pairs_iterator_t it = mItemPairs.begin();
for (; it != mItemPairs.end(); ++it)
{
LLPanel* item = (*it)->first;
+
+ // skip invisible child
+ if (!item->getVisible())
+ {
+ ++invisible_children_count;
+ continue;
+ }
+
height += item->getRect().getHeight();
}
- height += mItemPad * (mItemPairs.size() - 1);
+
+ // add paddings between items, excluding invisible ones
+ height += mItemPad * (mItemPairs.size() - invisible_children_count - 1);
LLRect rc = mItemsPanel->getRect();
S32 width = mItemsNoScrollWidth;
@@ -346,14 +417,18 @@ void LLFlatListView::rearrangeItems()
for (it2 = first_it; it2 != mItemPairs.end(); ++it2)
{
LLPanel* item = (*it2)->first;
+
+ // skip invisible child
+ if (!item->getVisible())
+ continue;
+
LLRect rc = item->getRect();
- if(it2 != first_it)
- {
- item_new_top -= (rc.getHeight() + mItemPad);
- }
rc.setLeftTopAndSize(rc.mLeft, item_new_top, width, rc.getHeight());
item->reshape(rc.getWidth(), rc.getHeight());
item->setRect(rc);
+
+ // move top for next item in list
+ item_new_top -= (rc.getHeight() + mItemPad);
}
}
@@ -443,6 +518,12 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
//a way of notifying panel of selection state changes
LLPanel* item = item_pair->first;
item->setValue(select ? SELECTED_EVENT : UNSELECTED_EVENT);
+
+ if (mCommitOnSelectionChange)
+ {
+ onCommit();
+ }
+
return true;
}
@@ -483,12 +564,82 @@ bool LLFlatListView::removeItemPair(item_pair_t* item_pair)
}
mItemsPanel->removeChild(item_pair->first);
- delete item_pair->first;
+ item_pair->first->die();
delete item_pair;
rearrangeItems();
+ notifyParentItemsRectChanged();
return true;
}
+void LLFlatListView::notifyParentItemsRectChanged()
+{
+ S32 comment_height = 0;
+
+ // take into account comment text height if exists
+ if (mNoItemsCommentTextbox && mNoItemsCommentTextbox->getVisible())
+ {
+ comment_height = mNoItemsCommentTextbox->getTextPixelHeight();
+ }
+
+ LLRect req_rect = getItemsRect();
+
+ // get maximum of items total height and comment text height
+ req_rect.setOriginAndSize(req_rect.mLeft, req_rect.mBottom, req_rect.getWidth(), llmax(req_rect.getHeight(), comment_height));
+
+ // take into account border size.
+ req_rect.stretch(getBorderWidth());
+
+ if (req_rect == mPrevNotifyParentRect)
+ return;
+
+ mPrevNotifyParentRect = req_rect;
+
+ LLSD params;
+ params["action"] = "size_changes";
+ params["width"] = req_rect.getWidth();
+ params["height"] = req_rect.getHeight();
+
+ getParent()->notifyParent(params);
+}
+
+void LLFlatListView::setNoItemsCommentVisible(bool visible) const
+{
+ if (mNoItemsCommentTextbox)
+ {
+ if (visible)
+ {
+ // We have to update child rect here because of issues with rect after reshaping while creating LLTextbox
+ // It is possible to have invalid LLRect if Flat List is in LLAccordionTab
+ LLRect comment_rect = getLocalRect();
+ comment_rect.stretch(-getBorderWidth());
+ mNoItemsCommentTextbox->setRect(comment_rect);
+ }
+ mNoItemsCommentTextbox->setVisible(visible);
+ }
+}
+
+void LLFlatListView::getItems(std::vector<LLPanel*>& items) const
+{
+ if (mItemPairs.empty()) return;
+
+ items.clear();
+ for (pairs_const_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
+ {
+ items.push_back((*it)->first);
+ }
+}
+
+void LLFlatListView::getValues(std::vector<LLSD>& values) const
+{
+ if (mItemPairs.empty()) return;
+
+ values.clear();
+ for (pairs_const_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
+ {
+ values.push_back((*it)->second);
+ }
+}
+//EOF
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index bd0b419f4f..af5a9cfa9b 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -33,10 +33,10 @@
#ifndef LL_LLFLATLISTVIEW_H
#define LL_LLFLATLISTVIEW_H
+#include "llpanel.h"
#include "llscrollcontainer.h"
-
-class LLPanel;
+class LLTextBox;
/**
* LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's.
@@ -62,6 +62,38 @@ class LLFlatListView : public LLScrollContainer
{
public:
+ /**
+ * Abstract comparator for comparing flat list items in a form of LLPanel
+ */
+ class ItemComparator
+ {
+ public:
+ ItemComparator() {};
+ virtual ~ItemComparator() {};
+
+ /** Returns true if item1 < item2, false otherwise */
+ virtual bool compare(const LLPanel* item1, const LLPanel* item2) const = 0;
+ };
+
+ /**
+ * Represents reverse comparator which acts as a decorator for a comparator that need to be reversed
+ */
+ class ItemReverseComparator : public ItemComparator
+ {
+ public:
+ ItemReverseComparator(const ItemComparator& comparator) : mComparator(comparator) {};
+ virtual ~ItemReverseComparator() {};
+
+ virtual bool compare(const LLPanel* item1, const LLPanel* item2) const
+ {
+ return mComparator.compare(item2, item1);
+ }
+
+ private:
+ const ItemComparator& mComparator;
+ };
+
+
struct Params : public LLInitParam::Block<Params, LLScrollContainer::Params>
{
/** turning on/off selection support */
@@ -85,18 +117,23 @@ public:
/** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ /** Returns full rect of child panel */
+ const LLRect& getItemsRect() const;
+
+ /** Returns distance between items */
+ const S32 getItemsPad() { return mItemPad; }
/**
* Adds and item and LLSD value associated with it to the list at specified position
* @return true if the item was added, false otherwise
*/
- virtual bool addItem(LLPanel* item, LLSD value = LLUUID::null, EAddPosition pos = ADD_BOTTOM);
+ virtual bool addItem(LLPanel * item, const LLSD& value = LLUUID::null, EAddPosition pos = ADD_BOTTOM);
/**
* Insert item_to_add along with associated value to the list right after the after_item.
* @return true if the item was successfully added, false otherwise
*/
- virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value = LLUUID::null);
+ virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value = LLUUID::null);
/**
* Remove specified item
@@ -114,13 +151,19 @@ public:
* Remove an item specified by uuid
* @return true if the item was removed, false otherwise
*/
- virtual bool removeItemByUUID(LLUUID& uuid);
+ virtual bool removeItemByUUID(const LLUUID& uuid);
/**
* Get an item by value
* @return the item as LLPanel if associated with value, NULL otherwise
*/
- virtual LLPanel* getItemByValue(LLSD& value) const;
+ virtual LLPanel* getItemByValue(const LLSD& value) const;
+
+ template<class T>
+ T* getTypedItemByValue(const LLSD& value) const
+ {
+ return dynamic_cast<T*>(getItemByValue(value));
+ }
/**
* Select or deselect specified item based on select
@@ -138,9 +181,17 @@ public:
* Select or deselect an item by associated uuid based on select
* @return true if succeed, false otherwise
*/
- virtual bool selectItemByUUID(LLUUID& uuid, bool select = true);
+ virtual bool selectItemByUUID(const LLUUID& uuid, bool select = true);
+ /**
+ * Get all panels stored in the list.
+ */
+ virtual void getItems(std::vector<LLPanel*>& items) const;
+ /**
+ * Get all items values.
+ */
+ virtual void getValues(std::vector<LLSD>& values) const;
/**
* Get LLSD associated with the first selected item
@@ -176,9 +227,23 @@ public:
virtual void getSelectedItems(std::vector<LLPanel*>& selected_items) const;
- /** Resets selection of items */
- virtual void resetSelection();
+ /**
+ * Resets selection of items.
+ *
+ * It calls onCommit callback if setCommitOnSelectionChange(bool b) was called with "true"
+ * argument for current Flat List.
+ * @param no_commit_on_deselection - if true onCommit callback will not be called
+ */
+ virtual void resetSelection(bool no_commit_on_deselection = false);
+ /**
+ * Sets comment text which will be shown in the list is it is empty.
+ *
+ * Textbox to hold passed text is created while this method is called at the first time.
+ *
+ * @param comment_text - string to be shown as a comment.
+ */
+ void setNoItemsCommentText( const std::string& comment_text);
/** Turn on/off multiple selection support */
void setAllowMultipleSelection(bool allow) { mMultipleSelection = allow; }
@@ -186,6 +251,8 @@ public:
/** Turn on/off selection support */
void setAllowSelection(bool can_select) { mAllowSelection = can_select; }
+ /** Sets flag whether onCommit should be fired if selection was changed */
+ void setCommitOnSelectionChange(bool b) { mCommitOnSelectionChange = b; }
/** Get number of selected items in the list */
U32 numSelected() const {return mSelectedItemPairs.size(); }
@@ -197,6 +264,14 @@ public:
/** Removes all items from the list */
virtual void clear();
+ /**
+ * Set comparator to use for future sorts.
+ *
+ * This class does NOT manage lifetime of the comparator
+ * but assumes that the comparator is always alive.
+ */
+ void setComparator(const ItemComparator* comp) { mItemComparator = comp; }
+ void sort();
protected:
@@ -207,6 +282,19 @@ protected:
typedef pairs_list_t::iterator pairs_iterator_t;
typedef pairs_list_t::const_iterator pairs_const_iterator_t;
+ /** An adapter for a ItemComparator */
+ struct ComparatorAdaptor
+ {
+ ComparatorAdaptor(const ItemComparator& comparator) : mComparator(comparator) {};
+
+ bool operator()(const item_pair_t* item_pair1, const item_pair_t* item_pair2)
+ {
+ return mComparator.compare(item_pair1->first, item_pair2->first);
+ }
+
+ const ItemComparator& mComparator;
+ };
+
friend class LLUICtrlFactory;
LLFlatListView(const LLFlatListView::Params& p);
@@ -214,7 +302,10 @@ protected:
/** Manage selection on mouse events */
void onItemMouseClick(item_pair_t* item_pair, MASK mask);
- /** Updates position of items */
+ /**
+ * Updates position of items.
+ * It does not take into account invisible items.
+ */
virtual void rearrangeItems();
virtual item_pair_t* getItemPair(LLPanel* item) const;
@@ -227,14 +318,27 @@ protected:
virtual bool removeItemPair(item_pair_t* item_pair);
+ /**
+ * Notify parent about changed size of internal controls with "size_changes" action
+ *
+ * Size includes Items Rect width and either Items Rect height or comment text height.
+ * Comment text height is included if comment text is set and visible.
+ * List border size is also included into notified size.
+ */
+ void notifyParentItemsRectChanged();
+
private:
void setItemsNoScrollWidth(S32 new_width) {mItemsNoScrollWidth = new_width - 2 * mBorderThickness;}
+ void setNoItemsCommentVisible(bool visible) const;
private:
+ /** Comparator to use when sorting the list. */
+ const ItemComparator* mItemComparator;
+
LLPanel* mItemsPanel;
S32 mItemsNoScrollWidth;
@@ -242,7 +346,7 @@ private:
S32 mBorderThickness;
/** Items padding */
- U32 mItemPad;
+ S32 mItemPad;
/** Selection support flag */
bool mAllowSelection;
@@ -250,6 +354,14 @@ private:
/** Multiselection support flag, ignored if selection is not supported */
bool mMultipleSelection;
+ /**
+ * Flag specified whether onCommit be called if selection is changed in the list.
+ *
+ * Can be ignored in the resetSelection() method.
+ * @see resetSelection()
+ */
+ bool mCommitOnSelectionChange;
+
bool mKeepOneItemSelected;
/** All pairs of the list */
@@ -257,6 +369,14 @@ private:
/** Selected pairs for faster access */
pairs_list_t mSelectedItemPairs;
+
+ /**
+ * Rectangle contained previous size of items parent notified last time.
+ * Is used to reduce amount of parentNotify() calls if size was not changed.
+ */
+ LLRect mPrevNotifyParentRect;
+
+ LLTextBox* mNoItemsCommentTextbox;
};
#endif
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index a57913683b..e0fe85ea01 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"
#include "llsdutil.h"
@@ -67,48 +68,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];
@@ -123,9 +111,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] =
@@ -134,13 +122,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;
@@ -249,7 +236,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),
@@ -304,6 +290,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 )
{
@@ -794,7 +786,7 @@ void LLFloater::setTitle( const std::string& title )
applyTitle();
}
-std::string LLFloater::getTitle()
+std::string LLFloater::getTitle() const
{
if (mTitle.empty())
{
@@ -812,7 +804,7 @@ void LLFloater::setShortTitle( const std::string& short_title )
applyTitle();
}
-std::string LLFloater::getShortTitle()
+std::string LLFloater::getShortTitle() const
{
if (mShortTitle.empty())
{
@@ -824,8 +816,6 @@ std::string LLFloater::getShortTitle()
}
}
-
-
BOOL LLFloater::canSnapTo(const LLView* other_view)
{
if (NULL == other_view)
@@ -1041,6 +1031,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");
@@ -1377,28 +1371,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)
{
@@ -1446,19 +1418,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());
}
}
@@ -1797,17 +1770,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 6208d52135..a320ba4a6f 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -103,9 +103,9 @@ public:
BUTTON_RESTORE,
BUTTON_MINIMIZE,
BUTTON_TEAR_OFF,
- BUTTON_EDIT,
BUTTON_DOCK,
BUTTON_UNDOCK,
+ BUTTON_HELP,
BUTTON_COUNT
};
@@ -175,9 +175,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();
@@ -258,12 +258,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:
@@ -333,7 +331,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;
@@ -352,11 +349,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 60ddbc6cb3..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
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index d0adadd6d3..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;
};
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/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 2b4aad5e83..a68b9cae57 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1446,8 +1446,8 @@ void LLNotifications::cancel(LLNotificationPtr pNotif)
{
llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
}
- updateItem(LLSD().insert("sigtype", "delete").insert("id", pNotif->id()), pNotif);
pNotif->cancel();
+ updateItem(LLSD().insert("sigtype", "delete").insert("id", pNotif->id()), pNotif);
}
void LLNotifications::update(const LLNotificationPtr pNotif)
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.cpp b/indra/llui/llscrollbar.cpp
index 172c4a9c65..ed150ac50c 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -66,7 +66,9 @@ LLScrollbar::Params::Params()
up_button("up_button"),
down_button("down_button"),
left_button("left_button"),
- right_button("right_button")
+ right_button("right_button"),
+ bg_visible("bg_visible", false),
+ bg_color("bg_color", LLColor4::black)
{
tab_stop = false;
}
@@ -92,7 +94,9 @@ LLScrollbar::LLScrollbar(const Params & p)
mThumbImageH(p.thumb_image_horizontal),
mTrackImageV(p.track_image_vertical),
mTrackImageH(p.track_image_horizontal),
- mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize"))
+ mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize")),
+ mBGVisible(p.bg_visible),
+ mBGColor(p.bg_color)
{
updateThumbRect();
@@ -482,6 +486,11 @@ void LLScrollbar::draw()
{
if (!getRect().isValid()) return;
+ if(mBGVisible)
+ {
+ gl_rect_2d(getLocalRect(), mBGColor.get(), TRUE);
+ }
+
S32 local_mouse_x;
S32 local_mouse_y;
LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index 30d906e04c..7e88b16561 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -66,8 +66,11 @@ public:
track_image_horizontal,
track_image_vertical;
+ Optional<bool> bg_visible;
+
Optional<LLUIColor> track_color,
- thumb_color;
+ thumb_color,
+ bg_color;
Optional<LLButton::Params> up_button;
Optional<LLButton::Params> down_button;
@@ -151,6 +154,9 @@ private:
LLUIColor mTrackColor;
LLUIColor mThumbColor;
+ LLUIColor mBGColor;
+
+ bool mBGVisible;
LLUIImagePtr mThumbImageV;
LLUIImagePtr mThumbImageH;
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 30a042cff1..cd5926fb6b 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -67,12 +67,10 @@ static LLDefaultChildRegistry::Register<LLScrollContainer> r("scroll_container")
#include "llscrollingpanellist.h"
#include "llcontainerview.h"
#include "llpanel.h"
-#include "lllistctrl.h"
static ScrollContainerRegistry::Register<LLScrollingPanelList> r1("scrolling_panel_list");
static ScrollContainerRegistry::Register<LLContainerView> r2("container_view");
static ScrollContainerRegistry::Register<LLPanel> r3("panel", &LLPanel::fromXML);
-static ScrollContainerRegistry::Register<LLListCtrl> r4("list");
LLScrollContainer::Params::Params()
: is_opaque("opaque"),
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 483106e857..54e42bf642 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -139,7 +139,9 @@ LLScrollListCtrl::Params::Params()
bg_stripe_color("bg_stripe_color"),
hovered_color("hovered_color"),
highlighted_color("highlighted_color"),
- contents("")
+ contents(""),
+ scroll_bar_bg_visible("scroll_bar_bg_visible"),
+ scroll_bar_bg_color("scroll_bar_bg_color")
{
name = "scroll_list";
mouse_opaque = true;
@@ -220,6 +222,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
sbparams.change_callback(boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2));
sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
sbparams.visible(false);
+ sbparams.bg_visible(p.scroll_bar_bg_visible);
+ sbparams.bg_color(p.scroll_bar_bg_color);
mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
addChild(mScrollbar);
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 49a49499ef..83b2f71037 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -83,7 +83,8 @@ public:
Optional<bool> has_border,
draw_heading,
draw_stripes,
- background_visible;
+ background_visible,
+ scroll_bar_bg_visible;
// layout
Optional<S32> column_padding,
@@ -104,7 +105,8 @@ public:
bg_readonly_color,
bg_stripe_color,
hovered_color,
- highlighted_color;
+ highlighted_color,
+ scroll_bar_bg_color;
Optional<Contents> contents;
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index 675a29a8b4..553b28ab87 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/lltextbox.h b/indra/llui/lltextbox.h
index 291d1dc517..0517325e70 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -109,6 +109,7 @@ public:
void setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); } // mouse down and up within button
const LLFontGL* getFont() const { return mDefaultFont; }
+ void setFont(const LLFontGL* font) { mDefaultFont = font; }
void reshapeToFitText();
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/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 b1bb5f23b9..1b71ba1769 100644
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
@@ -183,8 +183,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
@@ -200,6 +203,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.
@@ -519,8 +527,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);
@@ -543,10 +551,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 1d4b0261ad..a81b91df83 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -129,6 +129,7 @@ set(viewer_SOURCE_FILES
lleventinfo.cpp
lleventnotifier.cpp
lleventpoll.cpp
+ llexpandabletextbox.cpp
llface.cpp
llfasttimerview.cpp
llfavoritesbar.cpp
@@ -169,9 +170,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 +209,7 @@ set(viewer_SOURCE_FILES
llfloaterurlentry.cpp
llfloatervoicedevicesettings.cpp
llfloaterwater.cpp
+ llfloaterwhitelistentry.cpp
llfloaterwindlight.cpp
llfloaterworldmap.cpp
llfoldertype.cpp
@@ -234,6 +236,7 @@ set(viewer_SOURCE_FILES
llhudrender.cpp
llhudtext.cpp
llhudview.cpp
+ llimfloater.cpp
llimhandler.cpp
llimpanel.cpp
llimview.cpp
@@ -260,6 +263,9 @@ set(viewer_SOURCE_FILES
llmanipscale.cpp
llmaniptranslate.cpp
llmapresponders.cpp
+ llmediactrl.cpp
+ llmediadataresponder.cpp
+ llmediadatafetcher.cpp
llmediaremotectrl.cpp
llmemoryview.cpp
llmenucommands.cpp
@@ -278,8 +284,9 @@ set(viewer_SOURCE_FILES
llnetmap.cpp
llnotificationalerthandler.cpp
llnotificationgrouphandler.cpp
- llnotificationinfohandler.cpp
llnotificationmanager.cpp
+ llnotificationscripthandler.cpp
+ llnotificationtiphandler.cpp
llnotify.cpp
lloutputmonitorctrl.cpp
lloverlaybar.cpp
@@ -320,8 +327,12 @@ set(viewer_SOURCE_FILES
llpanelmediahud.cpp
llpanelmeprofile.cpp
llpanelmovetip.cpp
+ llpanelmediasettingsgeneral.cpp
+ llpanelmediasettingssecurity.cpp
+ llpanelmediasettingspermissions.cpp
llpanelobject.cpp
llpanelpeople.cpp
+ llpanelpeoplemenus.cpp
llpanelpermissions.cpp
llpanelpick.cpp
llpanelpicks.cpp
@@ -425,6 +436,8 @@ set(viewer_SOURCE_FILES
llviewerfloaterreg.cpp
llviewergenericmessage.cpp
llviewergesture.cpp
+ llviewerhelp.cpp
+ llviewerhelputil.cpp
llviewerinventory.cpp
llviewerjointattachment.cpp
llviewerjoint.cpp
@@ -490,7 +503,6 @@ set(viewer_SOURCE_FILES
llwearabledictionary.cpp
llwearablelist.cpp
llweb.cpp
- llmediactrl.cpp
llwind.cpp
llwlanimator.cpp
llwldaycycle.cpp
@@ -594,6 +606,7 @@ set(viewer_HEADER_FILES
lleventinfo.h
lleventnotifier.h
lleventpoll.h
+ llexpandabletextbox.h
llface.h
llfasttimerview.h
llfavoritesbar.h
@@ -634,9 +647,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
@@ -673,6 +686,7 @@ set(viewer_HEADER_FILES
llfloaterurlentry.h
llfloatervoicedevicesettings.h
llfloaterwater.h
+ llfloaterwhitelistentry.h
llfloaterwindlight.h
llfloaterworldmap.h
llfoldertype.h
@@ -699,6 +713,7 @@ set(viewer_HEADER_FILES
llhudrender.h
llhudtext.h
llhudview.h
+ llimfloater.h
llimpanel.h
llimview.h
llimcontrolpanel.h
@@ -725,6 +740,8 @@ set(viewer_HEADER_FILES
llmanipscale.h
llmaniptranslate.h
llmapresponders.h
+ llmediadataresponder.h
+ llmediadatafetcher.h
llmediaremotectrl.h
llmemoryview.h
llmenucommands.h
@@ -783,8 +800,12 @@ set(viewer_HEADER_FILES
llpanelmediahud.h
llpanelmeprofile.h
llpanelmovetip.h
+ llpanelmediasettingsgeneral.h
+ llpanelmediasettingssecurity.h
+ llpanelmediasettingspermissions.h
llpanelobject.h
llpanelpeople.h
+ llpanelpeoplemenus.h
llpanelpermissions.h
llpanelpick.h
llpanelpicks.h
@@ -893,6 +914,7 @@ set(viewer_HEADER_FILES
llviewerfloaterreg.h
llviewergenericmessage.h
llviewergesture.h
+ llviewerhelp.h
llviewerinventory.h
llviewerjoint.h
llviewerjointattachment.h
@@ -1583,6 +1605,7 @@ endif (INSTALL)
include(LLAddBuildTest)
SET(viewer_TEST_SOURCE_FILES
llagentaccess.cpp
+ llviewerhelputil.cpp
lllogininstance.cpp
)
set_source_files_properties(
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 dcaefbba39..a9bf9466de 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>
@@ -4884,18 +4895,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>10</integer>
- </map>
- <key>NavBarMargin</key>
- <map>
- <key>Comment</key>
- <string>Width of notification messages</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>60</integer>
+ <integer>35</integer>
</map>
<key>OverflowToastHeight</key>
<map>
@@ -5227,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>
@@ -5249,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>
@@ -7531,10 +7598,10 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ShowCameraAndMoveControls</key>
+ <key>ShowCameraButton</key>
<map>
<key>Comment</key>
- <string>Show/Hide Camera and Move controls in the bottom tray</string>
+ <string>Show/Hide Camera button in the bottom tray</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -7542,6 +7609,28 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>ShowMoveButton</key>
+ <map>
+ <key>Comment</key>
+ <string>Show/Hide Move button in the bottom tray</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ShowGestureButton</key>
+ <map>
+ <key>Comment</key>
+ <string>Show/Hide Gesture button in the bottom tray</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>ShowNavbarFavoritesPanel</key>
<map>
<key>Comment</key>
@@ -7564,6 +7653,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>GroupListShowIcons</key>
+ <map>
+ <key>Comment</key>
+ <string>Show/hide group icons in the group list</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>ShowPGSearchAll</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 6eb248ef74..50d378335e 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1684,7 +1684,80 @@ void LLAgentWearables::userRemoveAllClothesStep2(BOOL proceed)
}
}
-void LLAgentWearables::userRemoveAllAttachments()
+// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to
+// get attachments into desired state with minimal number of adds/removes.
+void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
+{
+ // Possible cases:
+ // already wearing but not in request set -> take off.
+ // already wearing and in request set -> leave alone.
+ // not wearing and in request set -> put on.
+
+ LLVOAvatar* avatarp = gAgent.getAvatarObject();
+ if (!avatarp)
+ {
+ llwarns << "No avatar found." << llendl;
+ return;
+ }
+
+ std::set<LLUUID> requested_item_ids;
+ std::set<LLUUID> current_item_ids;
+ for (S32 i=0; i<obj_item_array.count(); i++)
+ requested_item_ids.insert(obj_item_array[i].get()->getLinkedUUID());
+
+ // Build up list of objects to be removed and items currently attached.
+ llvo_vec_t objects_to_remove;
+ for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
+ iter != avatarp->mAttachmentPoints.end();)
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerObject* objectp = attachment->getObject();
+ if (objectp)
+ {
+ LLUUID object_item_id = attachment->getItemID();
+ if (requested_item_ids.find(object_item_id) != requested_item_ids.end())
+ {
+ // Object currently worn, was requested.
+ // Flag as currently worn so we won't have to add it again.
+ current_item_ids.insert(object_item_id);
+ }
+ else
+ {
+ // object currently worn, not requested.
+ objects_to_remove.push_back(objectp);
+ }
+ }
+ }
+
+ LLInventoryModel::item_array_t items_to_add;
+ for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin();
+ it != obj_item_array.end();
+ ++it)
+ {
+ LLUUID linked_id = (*it).get()->getLinkedUUID();
+ if (current_item_ids.find(linked_id) != current_item_ids.end())
+ {
+ // Requested attachment is already worn.
+ }
+ else
+ {
+ // Requested attachment is not worn yet.
+ items_to_add.push_back(*it);
+ }
+ }
+ // S32 remove_count = objects_to_remove.size();
+ // S32 add_count = items_to_add.size();
+ // llinfos << "remove " << remove_count << " add " << add_count << llendl;
+
+ // Remove everything in objects_to_remove
+ userRemoveMultipleAttachments(objects_to_remove);
+
+ // Add everything in items_to_add
+ userAttachMultipleAttachments(items_to_add);
+}
+
+void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove)
{
LLVOAvatar* avatarp = gAgent.getAvatarObject();
if (!avatarp)
@@ -1693,11 +1766,36 @@ void LLAgentWearables::userRemoveAllAttachments()
return;
}
+ if (objects_to_remove.empty())
+ return;
+
gMessageSystem->newMessage("ObjectDetach");
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+ for (llvo_vec_t::iterator it = objects_to_remove.begin();
+ it != objects_to_remove.end();
+ ++it)
+ {
+ LLViewerObject *objectp = *it;
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
+ }
+ gMessageSystem->sendReliable(gAgent.getRegionHost());
+}
+void LLAgentWearables::userRemoveAllAttachments()
+{
+ LLVOAvatar* avatarp = gAgent.getAvatarObject();
+ if (!avatarp)
+ {
+ llwarns << "No avatar found." << llendl;
+ return;
+ }
+
+ llvo_vec_t objects_to_remove;
+
for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
iter != avatarp->mAttachmentPoints.end();)
{
@@ -1705,12 +1803,9 @@ void LLAgentWearables::userRemoveAllAttachments()
LLViewerJointAttachment* attachment = curiter->second;
LLViewerObject* objectp = attachment->getObject();
if (objectp)
- {
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
- }
+ objects_to_remove.push_back(objectp);
}
- gMessageSystem->sendReliable(gAgent.getRegionHost());
+ userRemoveMultipleAttachments(objects_to_remove);
}
void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array)
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index f34b23e220..701ce7f05a 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -44,6 +44,7 @@ class LLInventoryItem;
class LLVOAvatarSelf;
class LLWearable;
class LLInitialWearablesFetch;
+class LLViewerObject;
class LLAgentWearables
{
@@ -181,6 +182,11 @@ public:
// MULTI-WEARABLE: assuming one wearable per type. Need upstream changes.
static void userRemoveWearable(void* userdata); // userdata is EWearableType
static void userRemoveAllClothes(void* userdata); // userdata is NULL
+
+ typedef std::vector<LLViewerObject*> llvo_vec_t;
+
+ static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
+ static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
static void userRemoveAllAttachments();
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index dfed1cb57a..3831846e2e 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -416,11 +416,11 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory
if (!append && total_links > 0)
{
- // Remove all current outfit folder links since we're now replacing the contents.
for (S32 i = 0; i < cof_items.count(); ++i)
{
gInventory.purgeObject(cof_items.get(i)->getUUID());
}
+ gInventory.notifyObservers();
}
LLPointer<LLUpdateAppearanceOnDestroy> link_waiter = new LLUpdateAppearanceOnDestroy;
@@ -532,19 +532,19 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory
const LLUUID &current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
// Processes that take time should show the busy cursor
//inc_busy_count();
-
+
LLInventoryModel::cat_array_t cof_cats;
LLInventoryModel::item_array_t cof_items;
gInventory.collectDescendents(current_outfit_id, cof_cats, cof_items,
LLInventoryModel::EXCLUDE_TRASH);
-
+
if (items.count() > 0)
{
- // Remove all current outfit folder links since we're now replacing the contents.
for (S32 i = 0; i < cof_items.count(); ++i)
{
gInventory.purgeObject(cof_items.get(i)->getUUID());
}
+ gInventory.notifyObservers();
}
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
@@ -696,21 +696,11 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,
}
}
-
- //If the folder doesn't contain only gestures, take off all attachments.
- if (!(wear_items.count() == 0 && obj_items.count() == 0 && gest_items.count() > 0) )
+ // Update attachments to match those requested.
+ LLVOAvatar* avatar = gAgent.getAvatarObject();
+ if( avatar )
{
- LLAgentWearables::userRemoveAllAttachments();
- }
-
- if( obj_items.count() > 0 )
- {
- // We've found some attachments. Add these.
- LLVOAvatar* avatar = gAgent.getAvatarObject();
- if( avatar )
- {
- LLAgentWearables::userAttachMultipleAttachments(obj_items);
- }
+ LLAgentWearables::userUpdateAttachments(obj_items);
}
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 7d5432904b..9b31f67cf3 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"
@@ -669,8 +670,6 @@ bool LLAppViewer::init()
mNumSessions++;
gSavedSettings.setS32("NumSessions", mNumSessions);
- gSavedSettings.setString("HelpLastVisitedURL",gSavedSettings.getString("HelpHomeURL"));
-
if (gSavedSettings.getBOOL("VerboseLogs"))
{
LLError::setPrintLocation(true);
@@ -700,6 +699,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/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 4819703e72..1676bb1d44 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -43,8 +43,11 @@
#include "llappviewer.h" // for gLastVersionChannel
#include "llcachename.h"
#include "llcallingcard.h" // for LLAvatarTracker
+#include "llgivemoney.h" // foe LLFloaterPay
#include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType
#include "llimview.h" // for gIMMgr
+#include "llmutelist.h"
+#include "llrecentpeople.h"
#include "llsidetray.h"
#include "llviewermessage.h" // for handle_lure
#include "llviewerregion.h"
@@ -206,6 +209,41 @@ void LLAvatarActions::showProfile(const LLUUID& id)
}
}
+// static
+void LLAvatarActions::pay(const LLUUID& id)
+{
+ LLNotification::Params params("BusyModePay");
+ params.functor.function(boost::bind(&LLAvatarActions::handlePay, _1, _2, id));
+
+ if (gAgent.getBusy())
+ {
+ // warn users of being in busy mode during a transaction
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 1);
+ }
+}
+
+// static
+void LLAvatarActions::toggleBlock(const LLUUID& id)
+{
+ std::string name;
+
+ gCacheName->getFullName(id, name);
+ LLMute mute(id, name, LLMute::AGENT);
+
+ if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
+ {
+ LLMuteList::getInstance()->remove(mute);
+ }
+ else
+ {
+ LLMuteList::getInstance()->add(mute);
+ }
+}
+
//== private methods ========================================================================================
// static
@@ -243,6 +281,19 @@ bool LLAvatarActions::handleRemove(const LLSD& notification, const LLSD& respons
}
// static
+bool LLAvatarActions::handlePay(const LLSD& notification, const LLSD& response, LLUUID avatar_id)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ gAgent.clearBusy();
+ }
+
+ LLFloaterPay::payDirectly(&give_money, avatar_id, /*is_group=*/FALSE);
+ return false;
+}
+
+// static
bool LLAvatarActions::callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
@@ -290,3 +341,11 @@ bool LLAvatarActions::isFriend(const LLUUID& id)
{
return ( NULL != LLAvatarTracker::instance().getBuddyInfo(id) );
}
+
+// static
+bool LLAvatarActions::isBlocked(const LLUUID& id)
+{
+ std::string name;
+ gCacheName->getFullName(id, name);
+ return LLMuteList::getInstance()->isMuted(id, name);
+}
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index f3c411e033..e911715c70 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -77,14 +77,30 @@ public:
static void showProfile(const LLUUID& id);
/**
+ * Give money to the avatar.
+ */
+ static void pay(const LLUUID& id);
+
+ /**
+ * Block/unblock the avatar.
+ */
+ static void toggleBlock(const LLUUID& id);
+
+ /**
* Return true if avatar with "id" is a friend
*/
static bool isFriend(const LLUUID& id);
+ /**
+ * @return true if the avatar is blocked
+ */
+ static bool isBlocked(const LLUUID& id);
+
private:
static bool callbackAddFriend(const LLSD& notification, const LLSD& response);
static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
static bool handleRemove(const LLSD& notification, const LLSD& response);
+ static bool handlePay(const LLSD& notification, const LLSD& response, LLUUID avatar_id);
// Just request friendship, no dialog.
static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message);
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index a8b1ff6c92..1d5fa9ffa7 100644
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -32,9 +32,10 @@
#include "llviewerprecompiledheaders.h"
+#include "llavatariconctrl.h"
+
#include "llagent.h"
#include "llavatarconstants.h"
-#include "llavatariconctrl.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llavataractions.h"
#include "llimview.h"
@@ -139,25 +140,37 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
{
if (value.isUUID())
{
+ LLAvatarPropertiesProcessor* app =
+ LLAvatarPropertiesProcessor::getInstance();
if (mAvatarId.notNull())
{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this);
+ app->removeObserver(mAvatarId, this);
}
if (mAvatarId != value.asUUID())
{
- LLAvatarPropertiesProcessor::getInstance()->addObserver(value.asUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(value.asUUID());
mAvatarId = value.asUUID();
- // Check if cache already contains image_id for that avatar
- avatar_image_map_t::iterator it;
+ // *BUG: This will return stale icons if a user changes their
+ // profile picture. Also, the online/offline tooltips will be
+ // out of date. However, otherwise we send too many upstream
+ // AvatarPropertiesRequest messages.
+ //
+ // *TODO: Implement a timeout on the icon cache, perhaps a day?,
+ // and make the cache update if a user views the full-profile for
+ // an avatar.
- it = sImagesCache.find(mAvatarId);
+ // Check if cache already contains image_id for that avatar
+ avatar_image_map_t::iterator it = sImagesCache.find(mAvatarId);
if (it != sImagesCache.end())
{
updateFromCache(it->second);
}
+ else
+ {
+ app->addObserver(value.asUUID(), this);
+ app->sendAvatarPropertiesRequest(value.asUUID());
+ }
}
}
@@ -181,21 +194,34 @@ void LLAvatarIconCtrl::updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data)
LLIconCtrl::setValue("default_profile_picture.j2c");
}
- // Update color of status symbol and tool tip
- if (data.flags & AVATAR_ONLINE)
+ // Can only see online status of friends
+ if (LLAvatarTracker::instance().isBuddy(mAvatarId))
{
- mStatusSymbol->setColor(LLColor4::green);
- if (mDrawTooltip)
+ if (LLAvatarTracker::instance().isBuddyOnline(mAvatarId))
{
- setToolTip((LLStringExplicit)"Online");
+ // Update color of status symbol and tool tip
+ mStatusSymbol->setColor(LLColor4::green);
+ if (mDrawTooltip)
+ {
+ setToolTip((LLStringExplicit)"Online");
+ }
+ }
+ else
+ {
+ mStatusSymbol->setColor(LLColor4::grey);
+ if (mDrawTooltip)
+ {
+ setToolTip((LLStringExplicit)"Offline");
+ }
}
}
else
{
+ // Not a buddy, no information
mStatusSymbol->setColor(LLColor4::grey);
if (mDrawTooltip)
{
- setToolTip((LLStringExplicit)"Offline");
+ setToolTip((LLStringExplicit)"");
}
}
}
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 2e64c10bb2..36f9780ad0 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -37,481 +37,233 @@
// newview
#include "llcallingcard.h" // for LLAvatarTracker
#include "llcachename.h"
-#include "lloutputmonitorctrl.h"
#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
-static LLDefaultChildRegistry::Register<LLAvatarListTmp> r_tmp("avatar_list_tmp");
-static const std::string COMMENT_TEXTBOX = "comment_text";
+// 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);
+ return haystack.find(needle_upper) != std::string::npos;
+}
+
+
+//comparators
+static const LLAvatarItemNameComparator NAME_COMPARATOR;
+static const LLFlatListView::ItemReverseComparator REVERSE_NAME_COMPARATOR(NAME_COMPARATOR);
LLAvatarList::Params::Params()
:
- volume_column_width("volume_column_width", 0)
- , online_go_first("online_go_first", true)
+volume_column_width("volume_column_width", 0)
+, online_go_first("online_go_first", true)
{
- draw_heading = true;
- draw_stripes = false;
- multi_select = false;
- column_padding = 0;
- search_column = COL_NAME;
- sort_column = COL_NAME;
}
+
+
LLAvatarList::LLAvatarList(const Params& p)
-: LLScrollListCtrl(p)
- , mHaveVolumeColumn(p.volume_column_width > 0)
- , mOnlineGoFirst(p.online_go_first)
+: LLFlatListView(p)
+, mOnlineGoFirst(p.online_go_first)
+, mContextMenu(NULL)
+, mDirty(true) // to force initial update
{
- setCommitOnSelectionChange(TRUE); // there's no such param in LLScrollListCtrl::Params
-
- // display a context menu appropriate for a list of avatar names
- setContextMenu(LLScrollListCtrl::MENU_AVATAR);
-
- // "volume" column
- {
- LLScrollListColumn::Params col_params;
- col_params.name = "volume";
- col_params.header.label = "Volume"; // *TODO: localize or remove the header
- col_params.width.pixel_width = p.volume_column_width;
- addColumn(col_params);
- }
-
- // "name" column
- {
- LLScrollListColumn::Params col_params;
- col_params.name = "name";
- col_params.header.label = "Name"; // *TODO: localize or remove the header
- col_params.width.dynamic_width = true;
- addColumn(col_params);
- }
-
- // "online status" column
- {
- LLScrollListColumn::Params col_params;
- col_params.name = "online";
- col_params.header.label = "Online"; // *TODO: localize or remove the header
- col_params.width.pixel_width = 0; // invisible column
- addColumn(col_params);
- }
-
-
- // invisible "id" column
- {
- LLScrollListColumn::Params col_params;
- col_params.name = "id";
- col_params.header.label = "ID"; // *TODO: localize or remove the header
- col_params.width.pixel_width = 0;
- addColumn(col_params);
- }
-
- // Primary sort = online status, secondary sort = name
- // The corresponding parameters don't work because we create columns dynamically.
- sortByColumnIndex(COL_NAME, TRUE);
- if (mOnlineGoFirst)
- sortByColumnIndex(COL_ONLINE, FALSE);
- setSearchColumn(COL_NAME);
+ setCommitOnSelectionChange(true);
+
+ // Set default sort order.
+ setComparator(&NAME_COMPARATOR);
}
// virtual
void LLAvatarList::draw()
{
- LLScrollListCtrl::draw();
- if (mHaveVolumeColumn)
- {
- updateVolume();
- }
-}
+ if (mDirty)
+ refresh();
-std::vector<LLUUID> LLAvatarList::getSelectedIDs()
-{
- LLUUID selected_id;
- std::vector<LLUUID> avatar_ids;
- std::vector<LLScrollListItem*> selected = getAllSelected();
- for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
- {
- avatar_ids.push_back((*itr)->getUUID());
- }
- return avatar_ids;
+ LLFlatListView::draw();
}
-void LLAvatarList::addItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
+void LLAvatarList::setNameFilter(const std::string& filter)
{
- std::string fullname;
-
- // Populate list item.
- LLSD element;
- element["id"] = id;
-
- // Update volume column (if we have one)
- {
- std::string icon = mHaveVolumeColumn ? getVolumeIcon(id) : "";
- LLSD& volume_column = element["columns"][COL_VOLUME];
- volume_column["column"] = "volume";
- volume_column["type"] = "icon";
- volume_column["value"] = icon;
- }
-
- LLSD& friend_column = element["columns"][COL_NAME];
- friend_column["column"] = "name";
- friend_column["value"] = name;
-
- LLSD& online_column = element["columns"][COL_ONLINE];
- online_column["column"] = "online";
- online_column["value"] = is_bold ? "1" : "0";
-
- LLScrollListItem* new_itemp = addElement(element, pos);
-
- // Indicate buddy online status.
- // (looks like parsing font parameters from LLSD is broken)
- if (is_bold)
+ if (mNameFilter != filter)
{
- LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(new_itemp->getColumn(COL_NAME));
- if (name_textp)
- name_textp->setFontStyle(LLFontGL::BOLD);
- else
- {
- llwarns << "Name column not found" << llendl;
- }
+ mNameFilter = filter;
+ setDirty();
}
}
-static bool findInsensitive(std::string haystack, const std::string& needle_upper)
+void LLAvatarList::sortByName()
{
- LLStringUtil::toUpper(haystack);
- return haystack.find(needle_upper) != std::string::npos;
+ 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_names = TRUE;
+ bool add_limit_exceeded = false;
+ bool modified = false;
+ bool have_filter = !mNameFilter.empty();
+
// Save selection.
- std::vector<LLUUID> selected_ids = getSelectedIDs();
- LLUUID current_id = getCurrentID();
- S32 pos = getScrollPos();
-
- std::vector<LLUUID>::const_iterator buddy_it = all_buddies.begin();
- deleteAllItems();
- for(; buddy_it != all_buddies.end(); ++buddy_it)
- {
- std::string name;
- const LLUUID& buddy_id = *buddy_it;
- have_names &= gCacheName->getFullName(buddy_id, name);
- if (name_filter != LLStringUtil::null && !findInsensitive(name, name_filter))
- continue;
- addItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
- }
+ std::vector<LLUUID> selected_ids;
+ getSelectedUUIDs(selected_ids);
+ LLUUID current_id = getSelectedUUID();
- // Changed item in place, need to request sort and update columns
- // because we might have changed data in a column on which the user
- // has already sorted. JC
- updateSort();
+ // Determine what to add and what to remove.
+ std::vector<LLUUID> added, removed;
+ LLAvatarList::computeDifference(getIDs(), added, removed);
- // re-select items
- selectMultiple(selected_ids);
- setCurrentByID(current_id);
-#if 0
- // Restore selection.
- if(selected_ids.size() > 0)
+ // Handle added items.
+ unsigned nadded = 0;
+ for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
{
- // only non-null if friends was already found. This may fail,
- // but we don't really care here, because refreshUI() will
- // clean up the interface.
- for(std::vector<LLUUID>::iterator itr = selected_ids.begin(); itr != selected_ids.end(); ++itr)
+ std::string name;
+ const LLUUID& buddy_id = *it;
+ have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+ if (!have_filter || findInsensitive(name, mNameFilter))
{
- setSelectedByValue(*itr, true);
+ if (nadded >= ADD_LIMIT)
+ {
+ add_limit_exceeded = true;
+ break;
+ }
+ else
+ {
+ addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+ modified = true;
+ nadded++;
+ }
}
}
-#endif
- setScrollPos(pos);
-
- updateLineHeight();
- LLRect rect = getRequiredRect();
-
- LLSD params;
- params["action"] = "size_changes";
- params["width"] = rect.getWidth();
- params["height"] = llmax(rect.getHeight(),20) + 5;
-
- getParent()->notifyParent(params);
-
- return have_names;
-}
-
-// static
-std::string LLAvatarList::getVolumeIcon(const LLUUID& id)
-{
- //
- // Determine icon appropriate for the current avatar volume.
- //
- // *TODO: remove this in favor of LLOutputMonitorCtrl
- // when ListView widget is implemented
- // which is capable of containing arbitrary widgets.
- //
- static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams<LLOutputMonitorCtrl>());
- bool muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id);
- F32 power = gVoiceClient->getCurrentPower(id);
- std::string icon;
- if (muted)
- {
- icon = default_monitor_params.image_mute.name;
- }
- else if (power == 0.f)
- {
- icon = default_monitor_params.image_off.name;
- }
- else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
+ // Handle removed items.
+ for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
{
- S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
- switch(icon_image_idx)
- {
- default:
- case 0:
- icon = default_monitor_params.image_on.name;
- break;
- case 1:
- icon = default_monitor_params.image_level_1.name;
- break;
- case 2:
- icon = default_monitor_params.image_level_2.name;
- break;
- }
+ removeItemByUUID(*it);
+ modified = true;
}
- else
- {
- // overdriven
- icon = default_monitor_params.image_level_3.name;
- }
-
- return icon;
-}
-
-// Update volume column for all list rows.
-void LLAvatarList::updateVolume()
-{
- item_list& items = getItemList();
- for (item_list::iterator item_it = items.begin();
- item_it != items.end();
- ++item_it)
+ // Handle filter.
+ if (have_filter)
{
- LLScrollListItem* itemp = (*item_it);
- LLUUID speaker_id = itemp->getUUID();
+ std::vector<LLSD> cur_values;
+ getValues(cur_values);
- LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME);
- if (icon_cell)
- icon_cell->setValue(getVolumeIcon(speaker_id));
+ for (std::vector<LLSD>::const_iterator it=cur_values.begin(); it != cur_values.end(); it++)
+ {
+ std::string name;
+ const LLUUID& buddy_id = it->asUUID();
+ have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+ if (!findInsensitive(name, mNameFilter))
+ {
+ removeItemByUUID(buddy_id);
+ modified = true;
+ }
+ }
}
-}
-
-
-
-
-#include "llavatarlistitem.h"
-
-LLAvatarListTmp::Params::Params()
-:
-volume_column_width("volume_column_width", 0)
-, online_go_first("online_go_first", true)
-{
-}
-
+ // Changed item in place, need to request sort and update columns
+ // because we might have changed data in a column on which the user
+ // has already sorted. JC
+ sort();
-LLAvatarListTmp::LLAvatarListTmp(const Params& p)
-: LLFlatListView(p)
-, mHaveVolumeColumn(p.volume_column_width > 0)
-, mOnlineGoFirst(p.online_go_first)
-{
- LLRect item_list_rect = getLocalRect();
- item_list_rect.stretch( -getBorderWidth());
-
- LLTextBox::Params text_p;
- text_p.name(COMMENT_TEXTBOX);
- text_p.border_visible(false);
- text_p.rect(item_list_rect);
- text_p.follows.flags(FOLLOWS_ALL);
- addChild(LLUICtrlFactory::create<LLTextBox>(text_p));
-}
+ // re-select items
+ // selectMultiple(selected_ids); // TODO: implement in LLFlatListView if need
+ selectItemByUUID(current_id);
-// virtual
-void LLAvatarListTmp::draw()
-{
- LLFlatListView::draw();
- if (mHaveVolumeColumn)
- {
- updateVolume();
- }
+ // If the name filter is specified and the names are incomplete,
+ // we need to re-update when the names are complete so that
+ // the filter can be applied correctly.
+ //
+ // Otherwise, if we have no filter then no need to update again
+ // because the items will update their names.
+ bool dirty = add_limit_exceeded || (have_filter && !have_names);
+ setDirty(dirty);
+
+ // Commit if we've added/removed items.
+ if (modified)
+ onCommit();
}
-std::vector<LLUUID> LLAvatarListTmp::getSelectedIDs()
-{
- LLUUID selected_id;
- std::vector<LLUUID> avatar_ids;
-
- getSelectedUUIDs(avatar_ids);
- return avatar_ids;
-}
-
-void LLAvatarListTmp::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
+void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
{
LLAvatarListItem* item = new LLAvatarListItem();
- item->showStatus(true);
+ item->showStatus(false);
item->showInfoBtn(true);
item->showSpeakingIndicator(true);
item->setName(name);
item->setAvatarId(id);
+ item->setContextMenu(mContextMenu);
item->childSetVisible("info_btn", false);
addItem(item, id, pos);
-
- setCommentVisible(false);
}
-BOOL LLAvatarListTmp::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
+void LLAvatarList::computeDifference(
+ const std::vector<LLUUID>& vnew_unsorted,
+ std::vector<LLUUID>& vadded,
+ std::vector<LLUUID>& vremoved)
{
- BOOL have_names = TRUE;
-
- // Save selection.
- std::vector<LLUUID> selected_ids = getSelectedIDs();
- LLUUID current_id = getSelectedUUID();
- LLRect pos = getScrolledViewRect();
+ std::vector<LLUUID> vcur;
+ std::vector<LLUUID> vnew = vnew_unsorted;
- std::vector<LLUUID>::const_iterator buddy_it = all_buddies.begin();
- clear();
- for(; buddy_it != all_buddies.end(); ++buddy_it)
+ // Convert LLSDs to LLUUIDs.
{
- std::string name;
- const LLUUID& buddy_id = *buddy_it;
- have_names &= gCacheName->getFullName(buddy_id, name);
- if (name_filter != LLStringUtil::null && !findInsensitive(name, name_filter))
- continue;
- addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
- }
-
- // Changed item in place, need to request sort and update columns
- // because we might have changed data in a column on which the user
- // has already sorted. JC
- // updateSort(); // TODO: implement sorting
+ std::vector<LLSD> vcur_values;
+ getValues(vcur_values);
- // re-select items
- // selectMultiple(selected_ids); // TODO: implement in LLFlatListView if need
- selectItemByUUID(current_id);
-
- scrollToShowRect(pos);
-
-
- setCommentVisible(false);
-
- return have_names;
-}
-
-
-const LLUUID LLAvatarListTmp::getCurrentID() const
-{
- return getSelectedUUID();
-}
+ for (size_t i=0; i<vcur_values.size(); i++)
+ vcur.push_back(vcur_values[i].asUUID());
+ }
-void LLAvatarListTmp::setCommentText(const std::string& comment_text)
-{
- getChild<LLTextBox>(COMMENT_TEXTBOX)->setValue(comment_text);
-}
+ 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);
-//////////////////////////////////////////////////////////////////////////
-// PROTECTED SECTION
-//////////////////////////////////////////////////////////////////////////
+ // what to remove
+ it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
+ vremoved.erase(it, vremoved.end());
-// virtual overridden
-bool LLAvatarListTmp::removeItemPair(item_pair_t* item_pair)
-{
- bool removed = LLFlatListView::removeItemPair(item_pair);
- setCommentVisible(size() == 0);
- return removed;
+ // what to add
+ it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
+ vadded.erase(it, vadded.end());
}
-
-//////////////////////////////////////////////////////////////////////////
-// PRIVATE SECTION
-//////////////////////////////////////////////////////////////////////////
-
-// static
-std::string LLAvatarListTmp::getVolumeIcon(const LLUUID& id)
+bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
{
- //
- // Determine icon appropriate for the current avatar volume.
- //
- // *TODO: remove this in favor of LLOutputMonitorCtrl
- // when ListView widget is implemented
- // which is capable of containing arbitrary widgets.
- //
- static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams<LLOutputMonitorCtrl>());
- bool muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id);
- F32 power = gVoiceClient->getCurrentPower(id);
- std::string icon;
-
- if (muted)
- {
- icon = default_monitor_params.image_mute.name;
- }
- else if (power == 0.f)
- {
- icon = default_monitor_params.image_off.name;
- }
- else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
- {
- S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
- switch(icon_image_idx)
- {
- default:
- case 0:
- icon = default_monitor_params.image_on.name;
- break;
- case 1:
- icon = default_monitor_params.image_level_1.name;
- break;
- case 2:
- icon = default_monitor_params.image_level_2.name;
- break;
- }
- }
- else
+ const LLAvatarListItem* avatar_item1 = dynamic_cast<const LLAvatarListItem*>(item1);
+ const LLAvatarListItem* avatar_item2 = dynamic_cast<const LLAvatarListItem*>(item2);
+
+ if (!avatar_item1 || !avatar_item2)
{
- // overdriven
- icon = default_monitor_params.image_level_3.name;
+ llerror("item1 and item2 cannot be null", 0);
+ return true;
}
- return icon;
+ return doCompare(avatar_item1, avatar_item2);
}
-// Update volume column for all list rows.
-void LLAvatarListTmp::updateVolume()
+bool LLAvatarItemNameComparator::doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const
{
- // TODO: implement via Listener
- /*
- item_list& items = getItemList();
+ std::string name1 = avatar_item1->getAvatarName();
+ std::string name2 = avatar_item2->getAvatarName();
- for (item_list::iterator item_it = items.begin();
- item_it != items.end();
- ++item_it)
- {
- LLScrollListItem* itemp = (*item_it);
- LLUUID speaker_id = itemp->getUUID();
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
- LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME);
- if (icon_cell)
- icon_cell->setValue(getVolumeIcon(speaker_id));
- }
- */
+ return name1 < name2;
}
-
-void LLAvatarListTmp::setCommentVisible(bool visible) const
-{
- getChildView(COMMENT_TEXTBOX)->setVisible(visible);
-}
-
-// EOF
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 639ed83ada..ec801645fe 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -33,88 +33,98 @@
#ifndef LL_LLAVATARLIST_H
#define LL_LLAVATARLIST_H
-#include <llscrolllistctrl.h>
+#include "llflatlistview.h"
+
+#include "llavatarlistitem.h"
-// *TODO: derive from ListView when it's ready.
-class LLAvatarList : public LLScrollListCtrl
+/**
+ * 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:
- struct Params : public LLInitParam::Block<Params, LLScrollListCtrl::Params>
+ typedef std::vector<LLUUID> uuid_vector_t;
+
+ struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
{
Optional<S32> volume_column_width;
Optional<bool> online_go_first;
Params();
};
- enum EColumnOrder
- {
- COL_VOLUME,
- COL_NAME,
- COL_ONLINE,
- COL_ID,
- };
-
LLAvatarList(const Params&);
virtual ~LLAvatarList() {}
- /*virtual*/ void draw();
+ 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; }
- BOOL update(const std::vector<LLUUID>& all_buddies,
- const std::string& name_filter = LLStringUtil::null);
+ void sortByName();
protected:
- std::vector<LLUUID> getSelectedIDs();
- void addItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+ 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,
+ std::vector<LLUUID>& vadded,
+ std::vector<LLUUID>& vremoved);
private:
- static std::string getVolumeIcon(const LLUUID& id); /// determine volume icon from current avatar volume
- void updateVolume(); // update volume for all avatars
- bool mHaveVolumeColumn;
bool mOnlineGoFirst;
-};
+ bool mDirty;
+ std::string mNameFilter;
+ uuid_vector_t mIDs;
-#include "llflatlistview.h"
+ LLAvatarListItem::ContextMenu* mContextMenu;
+};
-class LLAvatarListTmp : public LLFlatListView
+/** Abstract comparator for avatar items */
+class LLAvatarItemComparator : public LLFlatListView::ItemComparator
{
- LOG_CLASS(LLAvatarListTmp);
-public:
- struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
- {
- Optional<S32> volume_column_width;
- Optional<bool> online_go_first;
- Params();
- };
-
- LLAvatarListTmp(const Params&);
- virtual ~LLAvatarListTmp() {}
+ LOG_CLASS(LLAvatarItemComparator);
- /*virtual*/ void draw();
-
- BOOL update(const std::vector<LLUUID>& all_buddies,
- const std::string& name_filter = LLStringUtil::null);
+public:
+ LLAvatarItemComparator() {};
+ virtual ~LLAvatarItemComparator() {};
- const LLUUID getCurrentID() const;
- void setCommentText( const std::string& comment_text);
+ virtual bool compare(const LLPanel* item1, const LLPanel* item2) const;
protected:
- std::vector<LLUUID> getSelectedIDs();
- void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
- /*virtual*/ bool removeItemPair(item_pair_t* item_pair);
-private:
- static std::string getVolumeIcon(const LLUUID& id); /// determine volume icon from current avatar volume
- void updateVolume(); // update volume for all avatars
- void setCommentVisible(bool visible) const;
+ /**
+ * Returns true if avatar_item1 < avatar_item2, false otherwise
+ * Implement this method in your particular comparator.
+ * In Linux a compiler failed to build it using the name "compare", so it was renamed to doCompare
+ */
+ virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const = 0;
+};
- bool mHaveVolumeColumn;
- bool mOnlineGoFirst;
-};
+class LLAvatarItemNameComparator : public LLAvatarItemComparator
+{
+ LOG_CLASS(LLAvatarItemNameComparator);
+public:
+ LLAvatarItemNameComparator() {};
+ virtual ~LLAvatarItemNameComparator() {};
+protected:
+ virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const;
+};
#endif // LL_LLAVATARLIST_H
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index feae8202bc..665dffc8c6 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -48,7 +48,9 @@ LLAvatarListItem::LLAvatarListItem()
mAvatarName(NULL),
mStatus(NULL),
mSpeakingIndicator(NULL),
- mInfoBtn(NULL)
+ mInfoBtn(NULL),
+ mContextMenu(NULL),
+ mAvatarId(LLUUID::null)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml");
}
@@ -114,6 +116,15 @@ void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask)
LLPanel::onMouseLeave(x, y, mask);
}
+// virtual
+BOOL LLAvatarListItem::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (mContextMenu)
+ mContextMenu->show(this, const_cast<const LLUUID&>(mAvatarId), x, y);
+
+ return LLPanel::handleRightMouseDown(x, y, mask);
+}
+
void LLAvatarListItem::setStatus(const std::string& status)
{
mStatus->setValue(status);
@@ -127,13 +138,17 @@ void LLAvatarListItem::setName(const std::string& name)
void LLAvatarListItem::setAvatarId(const LLUUID& id)
{
+ mAvatarId = id;
mAvatarIcon->setValue(id);
mSpeakingIndicator->setSpeakerId(id);
+
+ // Set avatar name.
+ gCacheName->get(id, FALSE, boost::bind(&LLAvatarListItem::onNameCache, this, _2, _3));
}
void LLAvatarListItem::onInfoBtnClick()
{
- LLFloaterReg::showInstance("inspect_avatar", mAvatarIcon->getValue());
+ LLFloaterReg::showInstance("inspect_avatar", mAvatarId);
/* TODO fix positioning of inspector
localPointToScreen(mXPos, mYPos, &mXPos, &mYPos);
@@ -156,6 +171,21 @@ void LLAvatarListItem::onInfoBtnClick()
*/
}
+void LLAvatarListItem::showStatus(bool show_status)
+{
+ // *HACK: dirty hack until we can determine correct avatar status (EXT-1076).
+
+ if (show_status)
+ return;
+
+ LLRect name_rect = mAvatarName->getRect();
+ LLRect status_rect = mStatus->getRect();
+
+ mStatus->setVisible(show_status);
+ name_rect.mRight += (status_rect.mRight - name_rect.mRight);
+ mAvatarName->setRect(name_rect);
+}
+
void LLAvatarListItem::setValue( const LLSD& value )
{
if (!value.isMap()) return;;
@@ -163,3 +193,19 @@ void LLAvatarListItem::setValue( const LLSD& value )
childSetVisible("selected_icon", value["selected"]);
}
+const LLUUID& LLAvatarListItem::getAvatarId() const
+{
+ return mAvatarId;
+}
+
+const std::string LLAvatarListItem::getAvatarName() const
+{
+ return mAvatarName->getValue();
+}
+
+void LLAvatarListItem::onNameCache(const std::string& first_name, const std::string& last_name)
+{
+ std::string name = first_name + " " + last_name;
+ mAvatarName->setValue(name);
+ mAvatarName->setToolTip(name);
+}
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index dc5606e4c2..bde9250e4a 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -43,32 +43,48 @@ class LLAvatarIconCtrl;
class LLAvatarListItem : public LLPanel
{
public:
+ class ContextMenu
+ {
+ public:
+ virtual void show(LLView* spawning_view, const LLUUID& id, S32 x, S32 y) = 0;
+ };
+
LLAvatarListItem();
virtual ~LLAvatarListItem() {};
virtual BOOL postBuild();
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
+ virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual void setValue(const LLSD& value);
void setStatus(const std::string& status);
void setName(const std::string& name);
void setAvatarId(const LLUUID& id);
+
+ const LLUUID& getAvatarId() const;
+ const std::string getAvatarName() const;
void onInfoBtnClick();
void showSpeakingIndicator(bool show) { mSpeakingIndicator->setVisible(show); }
void showInfoBtn(bool show_info_btn) {mInfoBtn->setVisible(show_info_btn); }
- void showStatus(bool show_status) {mStatus->setVisible(show_status); }
+ void showStatus(bool show_status);
+ void setContextMenu(ContextMenu* menu) { mContextMenu = menu; }
private:
+ void onNameCache(const std::string& first_name, const std::string& last_name);
+
LLAvatarIconCtrl*mAvatarIcon;
LLTextBox* mAvatarName;
LLTextBox* mStatus;
LLOutputMonitorCtrl* mSpeakingIndicator;
LLButton* mInfoBtn;
+ ContextMenu* mContextMenu;
+
+ LLUUID mAvatarId;
};
#endif //LL_LLAVATARLISTITEM_H
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index edf6e84b68..e568b9c526 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -428,27 +428,10 @@ void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, voi
msg->getString(_PREHASH_Data, _PREHASH_Desc, pick_data.desc);
msg->getUUID(_PREHASH_Data, _PREHASH_SnapshotID, pick_data.snapshot_id);
- // "Location text" is actually the owner name, the original
- // name that owner gave the parcel, and the location.
- msg->getString(_PREHASH_Data, _PREHASH_User, pick_data.location_text);
- pick_data.location_text.append(", ");
-
+ msg->getString(_PREHASH_Data, _PREHASH_User, pick_data.user_name);
msg->getString(_PREHASH_Data, _PREHASH_OriginalName, pick_data.original_name);
- if (!pick_data.original_name.empty())
- {
- pick_data.location_text.append(pick_data.original_name);
- pick_data.location_text.append(", ");
- }
-
msg->getString(_PREHASH_Data, _PREHASH_SimName, pick_data.sim_name);
- pick_data.location_text.append(pick_data.sim_name);
- pick_data.location_text.append(" ");
-
msg->getVector3d(_PREHASH_Data, _PREHASH_PosGlobal, pick_data.pos_global);
- S32 region_x = llround((F32)pick_data.pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
- S32 region_y = llround((F32)pick_data.pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
- S32 region_z = llround((F32)pick_data.pos_global.mdV[VZ]);
- pick_data.location_text.append(llformat("(%d, %d, %d)", region_x, region_y, region_z));
msg->getS32(_PREHASH_Data, _PREHASH_SortOrder, pick_data.sort_order);
msg->getBOOL(_PREHASH_Data, _PREHASH_Enabled, pick_data.enabled);
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index 24675c44c0..79d109f1db 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -96,7 +96,7 @@ struct LLPickData
BOOL enabled;
//used only in read requests
- std::string location_text;
+ std::string user_name;
std::string original_name;
std::string sim_name;
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 06f9a86d8d..8771611b1c 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -37,7 +37,7 @@
#include "llchiclet.h"
#include "llfloaterreg.h"
#include "llflyoutbutton.h"
-#include "llimpanel.h" // for LLIMFloater
+#include "llimfloater.h" // for LLIMFloater
#include "lllayoutstack.h"
#include "llnearbychatbar.h"
#include "llsplitbutton.h"
@@ -59,13 +59,13 @@ LLBottomTray::LLBottomTray(const LLSD&)
mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
mSysWell = getChild<LLNotificationChiclet>("sys_well");
- mSysWell->setNotificationChicletWindow(LLFloaterReg::getInstance("syswell_window"));
+ // init mSysWell
+ // set handler for a Click operation
+ mSysWell->setClickCallback(boost::bind(&LLSysWellWindow::onChicletClick, LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window")));
mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));
- LLSplitButton* presets = getChild<LLSplitButton>("presets");
- presets->setSelectionCallback(LLFloaterCamera::onClickCameraPresets);
-
+ LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("CameraPresets.ChangeView",&LLFloaterCameraPresets::onClickCameraPresets);
LLIMMgr::getInstance()->addSessionObserver(this);
//this is to fix a crash that occurs because LLBottomTray is a singleton
@@ -79,16 +79,15 @@ LLBottomTray::LLBottomTray(const LLSD&)
BOOL LLBottomTray::postBuild()
{
- mCommitCallbackRegistrar.add("ShowCamMoveCtrls.Action", boost::bind(&LLBottomTray::onShowCamMoveCtrlsContextMenuItemClicked, this, _2));
- mEnableCallbackRegistrar.add("ShowCamMoveCtrls.EnableMenuItem", boost::bind(&LLBottomTray::onShowCamMoveCtrlsContextMenuItemEnabled, this, _2));
-
- mShowCamMoveCtrlsContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_camera_move_controls.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- gMenuHolder->addChild(mShowCamMoveCtrlsContextMenu);
+ mBottomTrayContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_bottomtray.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ gMenuHolder->addChild(mBottomTrayContextMenu);
mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar");
mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
mMovementPanel = getChild<LLPanel>("movement_panel");
+ mGestureCombo = getChild<LLComboBox>("Gesture");
mCamPanel = getChild<LLPanel>("cam_panel");
+ setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4));
return TRUE;
}
@@ -134,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;
@@ -222,54 +222,47 @@ void LLBottomTray::setVisible(BOOL visible)
}
}
-BOOL LLBottomTray::handleRightMouseDown(S32 x, S32 y, MASK mask)
+void LLBottomTray::showBottomTrayContextMenu(S32 x, S32 y, MASK mask)
{
- if (!LLPanel::handleRightMouseDown(x, y, mask))
+ // We should show BottomTrayContextMenu in last turn
+ if (mBottomTrayContextMenu && !LLMenuGL::sMenuContainer->getVisibleMenu())
{
- if (mShowCamMoveCtrlsContextMenu)
- {
- mShowCamMoveCtrlsContextMenu->buildDrawLabels();
- mShowCamMoveCtrlsContextMenu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, mShowCamMoveCtrlsContextMenu, x, y);
- }
+ //there are no other context menu (IM chiclet etc ), so we can show BottomTrayContextMenu
+ mBottomTrayContextMenu->buildDrawLabels();
+ mBottomTrayContextMenu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, mBottomTrayContextMenu, x, y);
+
}
-
- return TRUE;
}
-bool LLBottomTray::onShowCamMoveCtrlsContextMenuItemEnabled(const LLSD& userdata)
+void LLBottomTray::showGestureButton(BOOL visible)
{
- std::string item = userdata.asString();
-
- if (item == "show_camera_move_controls")
+ if (visible != mGestureCombo->getVisible())
{
- return gSavedSettings.getBOOL("ShowCameraAndMoveControls");
- }
-
- return FALSE;
-}
+ LLRect r = mNearbyChatBar->getRect();
-void LLBottomTray::onShowCamMoveCtrlsContextMenuItemClicked(const LLSD& userdata)
-{
- std::string item = userdata.asString();
+ mGestureCombo->setVisible(visible);
- if (item == "show_camera_move_controls")
- {
- BOOL state = !gSavedSettings.getBOOL("ShowCameraAndMoveControls");
+ if (!visible)
+ {
+ LLFloaterReg::hideFloaterInstance("gestures");
+ r.mRight -= mGestureCombo->getRect().getWidth();
+ }
+ else
+ {
+ r.mRight += mGestureCombo->getRect().getWidth();
+ }
- showCameraAndMoveControls(state);
- gSavedSettings.setBOOL("ShowCameraAndMoveControls", state);
+ mNearbyChatBar->setRect(r);
}
}
-void LLBottomTray::showCameraAndMoveControls(BOOL visible)
+void LLBottomTray::showMoveButton(BOOL visible)
{
- mCamPanel->setVisible(visible);
mMovementPanel->setVisible(visible);
+}
- if (!visible)
- {
- LLFloaterReg::hideFloaterInstance("moveview");
- LLFloaterReg::hideFloaterInstance("camera");
- }
+void LLBottomTray::showCameraButton(BOOL visible)
+{
+ mCamPanel->setVisible(visible);
}
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index c3c840ede0..b25dec7b92 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -37,6 +37,7 @@
#include "llpanel.h"
#include "llimview.h"
+#include "llcombobox.h"
class LLChicletPanel;
class LLLineEditor;
@@ -70,9 +71,11 @@ public:
virtual void onFocusLost();
virtual void setVisible(BOOL visible);
- virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ void showBottomTrayContextMenu(S32 x, S32 y, MASK mask);
- void showCameraAndMoveControls(BOOL visible);
+ void showGestureButton(BOOL visible);
+ void showMoveButton(BOOL visible);
+ void showCameraButton(BOOL visible);
private:
@@ -82,9 +85,6 @@ protected:
void onChicletClick(LLUICtrl* ctrl);
- bool onShowCamMoveCtrlsContextMenuItemEnabled(const LLSD& userdata);
- void onShowCamMoveCtrlsContextMenuItemClicked(const LLSD& userdata);
-
static void* createNearbyChatBar(void* userdata);
/**
@@ -97,9 +97,10 @@ protected:
LLTalkButton* mTalkBtn;
LLNearbyChatBar* mNearbyChatBar;
LLLayoutStack* mToolbarStack;
- LLMenuGL* mShowCamMoveCtrlsContextMenu;
+ LLMenuGL* mBottomTrayContextMenu;
LLPanel* mMovementPanel;
LLPanel* mCamPanel;
+ LLComboBox* mGestureCombo;
};
#endif // LL_LLBOTTOMPANEL_H
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 7326e39af3..e3440ee779 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -320,6 +320,12 @@ const LLRelationship* LLAvatarTracker::getBuddyInfo(const LLUUID& id) const
return get_ptr_in_map(mBuddyInfo, id);
}
+bool LLAvatarTracker::isBuddy(const LLUUID& id) const
+{
+ LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
+ return (info != NULL);
+}
+
// online status
void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online)
{
diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h
index 113f16de70..228239b5ba 100644
--- a/indra/newview/llcallingcard.h
+++ b/indra/newview/llcallingcard.h
@@ -125,6 +125,9 @@ public:
// get full info
const LLRelationship* getBuddyInfo(const LLUUID& id) const;
+ // Is this person a friend/buddy/calling card holder?
+ bool isBuddy(const LLUUID& id) const;
+
// online status
void setBuddyOnline(const LLUUID& id, bool is_online);
bool isBuddyOnline(const LLUUID& id) const;
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index a8373491cf..c4619dc57a 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -37,6 +37,8 @@
#include "llappviewer.h"
#include "llviewercontrol.h"
#include "llimview.h"
+#include "llbottomtray.h"
+#include "llviewerwindow.h"
#include <algorithm>
@@ -48,12 +50,34 @@ LLChannelManager::LLChannelManager()
LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLChannelManager::onLoginCompleted, this));
mChannelList.clear();
mStartUpChannel = NULL;
+
+ if(!gViewerWindow)
+ {
+ llerrs << "LLChannelManager::LLChannelManager() - viwer window is not initialized yet" << llendl;
+ }
}
//--------------------------------------------------------------------------
LLChannelManager::~LLChannelManager()
{
- //All channels are being deleted by Parent View
+ for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it)
+ {
+ delete (*it).channel;
+ }
+
+ mChannelList.clear();
+}
+
+//--------------------------------------------------------------------------
+LLScreenChannel* LLChannelManager::createNotificationChannel()
+{
+ // creating params for a channel
+ LLChannelManager::Params p;
+ p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID"));
+ p.channel_align = CA_RIGHT;
+
+ // Getting a Channel for our notifications
+ return dynamic_cast<LLScreenChannel*> (LLChannelManager::getInstance()->getChannel(p));
}
//--------------------------------------------------------------------------
@@ -61,20 +85,22 @@ void LLChannelManager::onLoginCompleted()
{
S32 away_notifications = 0;
+ // calc a number of all offline notifications
for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it)
{
+ // don't calc notifications for Nearby Chat
if((*it).channel->getChannelID() == LLUUID(gSavedSettings.getString("NearByChatChannelUUID")))
{
continue;
}
+ // don't calc notifications for channels that always show their notifications
if(!(*it).channel->getDisplayToastsAlways())
{
away_notifications +=(*it).channel->getNumberOfHiddenToasts();
}
}
- // *TODO: calculate IM notifications
away_notifications += gIMMgr->getNumberOfUnreadIM();
if(!away_notifications)
@@ -83,10 +109,10 @@ void LLChannelManager::onLoginCompleted()
return;
}
+ // create a channel for the StartUp Toast
LLChannelManager::Params p;
p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
- p.channel_right_bound = getRootView()->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
- p.channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+ p.channel_align = CA_RIGHT;
mStartUpChannel = createChannel(p);
if(!mStartUpChannel)
@@ -95,8 +121,13 @@ void LLChannelManager::onLoginCompleted()
return;
}
+ // init channel's position and size
+ S32 channel_right_bound = gViewerWindow->getWorldViewRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+ mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
mStartUpChannel->setShowToasts(true);
- static_cast<LLUICtrl*>(mStartUpChannel)->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
+
+ mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("ChannelBottomPanelMargin"), gSavedSettings.getS32("StartUpToastTime"));
}
@@ -107,62 +138,70 @@ void LLChannelManager::onStartUpToastClose()
{
mStartUpChannel->setVisible(FALSE);
mStartUpChannel->closeStartUpToast();
- getRootView()->removeChild(mStartUpChannel);
removeChannelByID(LLUUID(gSavedSettings.getString("StartUpChannelUUID")));
delete mStartUpChannel;
mStartUpChannel = NULL;
}
- // set StartUp Toast Flag
+ // set StartUp Toast Flag to allow all other channels to show incoming toasts
LLScreenChannel::setStartUpToastShown();
- // allow all other channels to show incoming toasts
- for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it)
- {
- (*it).channel->setShowToasts(true);
- }
-
// force NEARBY CHAT CHANNEL to repost all toasts if present
- LLScreenChannel* nearby_channel = getChannelByID(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);
}
//--------------------------------------------------------------------------
+
+LLScreenChannelBase* LLChannelManager::addChannel(LLScreenChannelBase* channel)
+{
+ if(!channel)
+ return 0;
+
+ ChannelElem new_elem;
+ new_elem.id = channel->getChannelID();
+ new_elem.channel = channel;
+
+ mChannelList.push_back(new_elem);
+
+ return channel;
+}
+
LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
{
- LLScreenChannel* new_channel = NULL;
+ LLScreenChannel* new_channel = new LLScreenChannel(p.id);
- if(!p.chiclet)
+ if(!new_channel)
{
- new_channel = getChannelByID(p.id);
+ llerrs << "LLChannelManager::getChannel(LLChannelManager::Params& p) - can't create a channel!" << llendl;
}
else
{
- new_channel = getChannelByChiclet(p.chiclet);
+ new_channel->setToastAlignment(p.toast_align);
+ new_channel->setChannelAlignment(p.channel_align);
+ new_channel->setDisplayToastsAlways(p.display_toasts_always);
+
+ addChannel(new_channel);
}
+ return new_channel;
+}
+
+LLScreenChannelBase* LLChannelManager::getChannel(LLChannelManager::Params& p)
+{
+ LLScreenChannelBase* new_channel = findChannelByID(p.id);
if(new_channel)
return new_channel;
- new_channel = new LLScreenChannel(p.id);
- getRootView()->addChild(new_channel);
- new_channel->init(p.channel_right_bound - p.channel_width, p.channel_right_bound);
- new_channel->setToastAlignment(p.align);
- new_channel->setDisplayToastsAlways(p.display_toasts_always);
-
- ChannelElem new_elem;
- new_elem.id = p.id;
- new_elem.chiclet = p.chiclet;
- new_elem.channel = new_channel;
-
- mChannelList.push_back(new_elem); //TODO: remove chiclet from ScreenChannel?
+ return createChannel(p);
- return new_channel;
}
//--------------------------------------------------------------------------
-LLScreenChannel* LLChannelManager::getChannelByID(const LLUUID id)
+LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID id)
{
std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
if(it != mChannelList.end())
@@ -174,34 +213,6 @@ LLScreenChannel* LLChannelManager::getChannelByID(const LLUUID id)
}
//--------------------------------------------------------------------------
-LLScreenChannel* LLChannelManager::getChannelByChiclet(const LLChiclet* chiclet)
-{
- std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), chiclet);
- if(it != mChannelList.end())
- {
- return (*it).channel;
- }
-
- return NULL;
-}
-
-//--------------------------------------------------------------------------
-void LLChannelManager::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it)
- {
- if((*it).channel->getToastAlignment() == NA_CENTRE)
- {
- LLRect channel_rect = (*it).channel->getRect();
- S32 screen_width = getRootView()->getRect().getWidth();
- channel_rect.setLeftTopAndSize(screen_width/2, channel_rect.mTop, channel_rect.getWidth(), channel_rect.getHeight());
- (*it).channel->setRect(channel_rect);
- (*it).channel->showToasts();
- }
- }
-}
-
-//--------------------------------------------------------------------------
void LLChannelManager::removeChannelByID(const LLUUID id)
{
std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
@@ -212,18 +223,5 @@ void LLChannelManager::removeChannelByID(const LLUUID id)
}
//--------------------------------------------------------------------------
-void LLChannelManager::removeChannelByChiclet(const LLChiclet* chiclet)
-{
- std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), chiclet);
- if(it != mChannelList.end())
- {
- mChannelList.erase(it);
- }
-}
-
-//--------------------------------------------------------------------------
-
-
-
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index e26c96b62e..b927d369cd 100644
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
@@ -34,7 +34,6 @@
#define LL_LLCHANNELMANAGER_H
-#include "llchiclet.h"
#include "llscreenchannel.h"
#include "lluuid.h"
@@ -48,36 +47,30 @@ namespace LLNotificationsUI
* Manager for screen channels.
* Responsible for instantiating and retrieving screen channels.
*/
-class LLChannelManager : public LLUICtrl, public LLSingleton<LLChannelManager>
+class LLChannelManager : public LLSingleton<LLChannelManager>
{
public:
- struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ struct Params
{
- LLUUID id;
- LLChiclet* chiclet;
- S32 channel_right_bound;
- S32 channel_width;
- bool display_toasts_always;
- EToastAlignment align;
-
- Params(): id(LLUUID("")), chiclet(NULL),
- channel_right_bound(0), channel_width(0),
- display_toasts_always(false), align(NA_BOTTOM)
+ LLUUID id;
+ bool display_toasts_always;
+ EToastAlignment toast_align;
+ EChannelAlignment channel_align;
+
+ Params(): id(LLUUID("")), display_toasts_always(false), toast_align(NA_BOTTOM), channel_align(CA_LEFT)
{}
};
struct ChannelElem
{
LLUUID id;
- LLChiclet* chiclet;
- LLScreenChannel* channel;
+ LLScreenChannelBase* channel;
- ChannelElem() : id(LLUUID("")), chiclet(NULL), channel(NULL) { }
+ ChannelElem() : id(LLUUID("")), channel(NULL) { }
ChannelElem(const ChannelElem &elem)
{
id = elem.id;
- chiclet = elem.chiclet;
channel = elem.channel;
}
@@ -85,12 +78,6 @@ public:
{
return (id == id_op);
}
-
- bool operator == (const LLChiclet* chiclet_op) const
- {
- return (chiclet == chiclet_op);
- }
-
};
LLChannelManager();
@@ -101,20 +88,24 @@ public:
// removes a channel intended for the startup toast and allows other channels to show their toasts
void onStartUpToastClose();
- //TODO: make protected? in order to be shure that channels are created only by notification handlers
- LLScreenChannel* createChannel(LLChannelManager::Params& p);
+ // creates a new ScreenChannel according to the given parameters or returns existing if present
+ LLScreenChannelBase* getChannel(LLChannelManager::Params& p);
+
+ LLScreenChannelBase* addChannel(LLScreenChannelBase* channel);
+
+ // returns a channel by its ID
+ LLScreenChannelBase* findChannelByID(const LLUUID id);
- LLScreenChannel* getChannelByID(const LLUUID id);
- LLScreenChannel* getChannelByChiclet(const LLChiclet* chiclet);
+ // creator of the Notification channel, that is used in more than one handler
+ LLScreenChannel* createNotificationChannel();
// remove channel methods
void removeChannelByID(const LLUUID id);
- void removeChannelByChiclet(const LLChiclet* chiclet);
-
- void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
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 a2dc97f7f5..98e492cada 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -38,6 +38,7 @@
#include "llgroupactions.h"
#include "lliconctrl.h"
#include "llimpanel.h" // LLFloaterIMPanel
+#include "llimfloater.h"
#include "llimview.h"
#include "llfloaterreg.h"
#include "lllocalcliprect.h"
@@ -47,6 +48,8 @@
#include "llvoiceclient.h"
#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");
@@ -84,7 +87,6 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p)
: LLChiclet(p)
, mButton(NULL)
, mCounterCtrl(NULL)
-, mNotificationChicletWindow(NULL)
{
LLButton::Params button_params = p.button;
button_params.rect(p.rect());
@@ -94,6 +96,11 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p)
LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
addChild(mCounterCtrl);
+
+ // connect counter handlers to the signals
+ connectCounterUpdatersToSignal("notify");
+ connectCounterUpdatersToSignal("groupnotify");
+ connectCounterUpdatersToSignal("notifytoast");
}
LLNotificationChiclet::~LLNotificationChiclet()
@@ -101,6 +108,25 @@ LLNotificationChiclet::~LLNotificationChiclet()
}
+void LLNotificationChiclet::connectCounterUpdatersToSignal(std::string notification_type)
+{
+ LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
+ LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
+ if(n_handler)
+ {
+ if(notification_type == "notifytoast")
+ {
+ n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::updateUreadIMNotifications, this));
+ n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::updateUreadIMNotifications, this));
+ }
+ else
+ {
+ n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this));
+ n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this));
+ }
+ }
+}
+
void LLNotificationChiclet::setCounter(S32 counter)
{
mCounterCtrl->setCounter(counter);
@@ -218,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;
}
@@ -259,7 +295,13 @@ LLIMP2PChiclet::Params::Params()
rect(LLRect(0, 25, 45, 0));
avatar_icon.name("avatar_icon");
- avatar_icon.rect(LLRect(0, 25, 25, 0));
+ 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);
unread_notifications.name("unread");
@@ -432,7 +474,12 @@ LLIMGroupChiclet::Params::Params()
rect(LLRect(0, 25, 45, 0));
group_icon.name("group_icon");
- group_icon.rect(LLRect(0, 25, 25, 0));
+
+ // *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");
unread_notifications.rect(LLRect(25, 25, 45, 0));
@@ -846,6 +893,27 @@ void LLChicletPanel::removeAll()
showScrollButtonsIfNeeded();
}
+void LLChicletPanel::scrollToChiclet(const LLChiclet* chiclet)
+{
+ const LLRect& rect = chiclet->getRect();
+
+ if (rect.mLeft < 0)
+ {
+ scroll(llabs(rect.mLeft));
+ showScrollButtonsIfNeeded();
+ }
+ else
+ {
+ S32 scrollWidth = mScrollArea->getRect().getWidth();
+
+ if (rect.mRight > scrollWidth)
+ {
+ scroll(-llabs(rect.mRight - scrollWidth));
+ showScrollButtonsIfNeeded();
+ }
+ }
+}
+
void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )
{
LLPanel::reshape(width,height,called_from_parent);
@@ -861,7 +929,7 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )
width, height - scroll_button_rect.getHeight()));
mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD,
- height + 7, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
+ height, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
mShowControls = width > mMinWidth;
mScrollArea->setVisible(mShowControls);
@@ -1117,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);
@@ -1125,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 52bd7dbc31..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() {};
@@ -548,9 +549,6 @@ public:
/*virtual*/ ~ LLNotificationChiclet();
- // Notification Chiclet Window
- void setNotificationChicletWindow(LLFloater* wnd) { mNotificationChicletWindow = wnd; }
-
// methods for updating a number of unread System or IM notifications
void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications + mUreadIMNotifications); }
void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications + mUreadIMNotifications); }
@@ -558,11 +556,12 @@ public:
void setToggleState(BOOL toggled);
protected:
+ // connect counter updaters to the corresponding signals
+ void connectCounterUpdatersToSignal(std::string notification_type);
+
LLNotificationChiclet(const Params& p);
friend class LLUICtrlFactory;
- LLFloater* mNotificationChicletWindow;
-
static S32 mUreadSystemNotifications;
static S32 mUreadIMNotifications;
@@ -644,6 +643,11 @@ public:
*/
void removeAll();
+ /*
+ * Scrolls the panel to the specified chiclet
+ */
+ void scrollToChiclet(const LLChiclet* chiclet);
+
boost::signals2::connection setChicletClickedCallback(
const commit_callback_t& cb);
@@ -814,6 +818,8 @@ T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S3
return NULL;
}
+ scrollToChiclet(chiclet);
+
chiclet->setSessionId(session_id);
return chiclet;
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/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
new file mode 100644
index 0000000000..131f9ceaf0
--- /dev/null
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -0,0 +1,508 @@
+/**
+ * @file llexpandabletextbox.cpp
+ * @brief LLExpandableTextBox and related class implementations
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-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 "llexpandabletextbox.h"
+
+#include "llscrollcontainer.h"
+
+static LLDefaultChildRegistry::Register<LLExpandableTextBox> t1("expandable_text");
+
+LLExpandableTextBox::LLTextBoxEx::Params::Params()
+: expand_textbox("expand_textbox")
+{
+}
+
+LLExpandableTextBox::LLTextBoxEx::LLTextBoxEx(const Params& p)
+: LLTextBox(p)
+{
+ setIsChrome(TRUE);
+
+ LLTextBox::Params params = p.expand_textbox;
+ mExpandTextBox = LLUICtrlFactory::create<LLTextBox>(params);
+ addChild(mExpandTextBox);
+
+ LLRect rc = getLocalRect();
+ rc.mRight -= getHPad();
+ rc.mLeft = rc.mRight - mExpandTextBox->getTextPixelWidth();
+ rc.mTop = mExpandTextBox->getTextPixelHeight();
+ mExpandTextBox->setRect(rc);
+}
+
+BOOL LLExpandableTextBox::LLTextBoxEx::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ BOOL ret = LLTextBox::handleMouseUp(x, y, mask);
+
+ if(mExpandTextBox->getRect().pointInRect(x, y))
+ {
+ onCommit();
+ }
+
+ return ret;
+}
+
+void LLExpandableTextBox::LLTextBoxEx::draw()
+{
+ // draw text box
+ LLTextBox::draw();
+ // force text box to draw children
+ LLUICtrl::draw();
+}
+
+void LLExpandableTextBox::LLTextBoxEx::drawText( S32 x, S32 y, const LLWString &text, const LLColor4& color )
+{
+ // *NOTE:dzaporozhan:
+ // Copy/paste from LLTextBox::drawText in order to modify last
+ // line width if needed and who "More" link
+ F32 alpha = getDrawContext().mAlpha;
+ if (mSegments.size() > 1)
+ {
+ // we have Urls (or other multi-styled segments)
+ drawTextSegments(x, y, text);
+ }
+ else if( mLineLengthList.empty() )
+ {
+ // simple case of 1 line of text in one style
+ mDefaultFont->render(text, 0, (F32)x, (F32)y, color % alpha,
+ mHAlign, mVAlign,
+ 0,
+ mShadowType,
+ S32_MAX, getRect().getWidth(), NULL, mUseEllipses);
+
+ mExpandTextBox->setVisible(FALSE);
+ }
+ else
+ {
+ // simple case of multiple lines of text, all in the same style
+ S32 cur_pos = 0;
+ for (std::vector<S32>::iterator iter = mLineLengthList.begin();
+ iter != mLineLengthList.end(); ++iter)
+ {
+ S32 line_length = *iter;
+ S32 line_height = llfloor(mDefaultFont->getLineHeight()) + mLineSpacing;
+ S32 max_pixels = getRect().getWidth();
+
+ if(iter + 1 != mLineLengthList.end()
+ && y - line_height < line_height)
+ {
+ max_pixels = getCropTextWidth();
+ }
+
+ mDefaultFont->render(text, cur_pos, (F32)x, (F32)y, color % alpha,
+ mHAlign, mVAlign,
+ 0,
+ mShadowType,
+ line_length, max_pixels, NULL, mUseEllipses );
+
+ cur_pos += line_length + 1;
+
+ y -= line_height;
+ if(y < line_height)
+ {
+ if( mLineLengthList.end() != iter + 1 )
+ {
+ showExpandText(y);
+ }
+ else
+ {
+ hideExpandText();
+ }
+ break;
+ }
+ }
+ }
+}
+
+void LLExpandableTextBox::LLTextBoxEx::showExpandText(S32 y)
+{
+ LLRect rc = mExpandTextBox->getRect();
+ rc.mTop = y + mExpandTextBox->getTextPixelHeight();
+ rc.mBottom = y;
+ mExpandTextBox->setRect(rc);
+ mExpandTextBox->setVisible(TRUE);
+}
+
+void LLExpandableTextBox::LLTextBoxEx::hideExpandText()
+{
+ mExpandTextBox->setVisible(FALSE);
+}
+
+S32 LLExpandableTextBox::LLTextBoxEx::getCropTextWidth()
+{
+ return mExpandTextBox->getRect().mLeft - getHPad() * 2;
+}
+
+void LLExpandableTextBox::LLTextBoxEx::drawTextSegments(S32 init_x, S32 init_y, const LLWString &text)
+{
+ // *NOTE:dzaporozhan:
+ // Copy/paste from LLTextBox::drawTextSegments in order to modify last
+ // line width if needed and who "More" link
+ F32 alpha = getDrawContext().mAlpha;
+
+ const S32 text_len = text.length();
+ if (text_len <= 0)
+ {
+ return;
+ }
+
+ S32 cur_line = 0;
+ S32 num_lines = getLineCount();
+ S32 line_start = getLineStart(cur_line);
+ S32 line_height = llround( mDefaultFont->getLineHeight() ) + mLineSpacing;
+ F32 text_y = (F32) init_y;
+ segment_set_t::iterator cur_seg = mSegments.begin();
+
+ // render a line of text at a time
+ const LLRect textRect = getLocalRect();
+ while((textRect.mBottom <= text_y) && (cur_line < num_lines))
+ {
+ S32 next_start = -1;
+ S32 line_end = text_len;
+
+ if ((cur_line + 1) < num_lines)
+ {
+ next_start = getLineStart(cur_line + 1);
+ line_end = next_start;
+ }
+ if ( text[line_end-1] == '\n' )
+ {
+ --line_end;
+ }
+
+ // render all segments on this line
+ F32 text_x = init_x;
+ S32 seg_start = line_start;
+ while (seg_start < line_end && cur_seg != mSegments.end())
+ {
+ // move to the next segment (or continue the previous one)
+ LLTextSegment *cur_segment = *cur_seg;
+ while (cur_segment->getEnd() <= seg_start)
+ {
+ if (++cur_seg == mSegments.end())
+ {
+ return;
+ }
+ cur_segment = *cur_seg;
+ }
+
+ // Draw a segment within the line
+ S32 clipped_end = llmin( line_end, cur_segment->getEnd() );
+ S32 clipped_len = clipped_end - seg_start;
+ if( clipped_len > 0 )
+ {
+ LLStyleSP style = cur_segment->getStyle();
+ if (style && style->isVisible())
+ {
+ // work out the color for the segment
+ LLColor4 color ;
+ if (getEnabled())
+ {
+ color = style->isLink() ? mLinkColor.get() : mTextColor.get();
+ }
+ else
+ {
+ color = mDisabledColor.get();
+ }
+ color = color % alpha;
+
+ S32 max_pixels = textRect.getWidth();
+
+ if(cur_line + 1 < num_lines
+ && text_y - line_height < line_height)
+ {
+ max_pixels = getCropTextWidth();
+ }
+
+ // render a single line worth for this segment
+ mDefaultFont->render(text, seg_start, text_x, text_y, color,
+ mHAlign, mVAlign, 0, mShadowType, clipped_len,
+ max_pixels, &text_x, mUseEllipses);
+ }
+
+ seg_start += clipped_len;
+ }
+ }
+
+ // move down one line
+ text_y -= (F32)line_height;
+ line_start = next_start;
+ cur_line++;
+ if(text_y < line_height)
+ {
+ if( cur_line < num_lines )
+ {
+ showExpandText((S32)text_y);
+ }
+ else
+ {
+ hideExpandText();
+ }
+ break;
+ }
+ }
+}
+
+S32 LLExpandableTextBox::LLTextBoxEx::getVerticalTextDelta()
+{
+ S32 text_height = getTextPixelHeight();
+ S32 textbox_height = getRect().getHeight();
+
+ return text_height - textbox_height;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLExpandableTextBox::Params::Params()
+: textbox("textbox")
+, scroll("scroll")
+, max_height("max_height", 0)
+, bg_visible("bg_visible", false)
+, expanded_bg_visible("expanded_bg_visible", true)
+, bg_color("bg_color", LLColor4::black)
+, expanded_bg_color("expanded_bg_color", LLColor4::black)
+{
+}
+
+LLExpandableTextBox::LLExpandableTextBox(const Params& p)
+: LLUICtrl(p)
+, mMaxHeight(p.max_height)
+, mBGVisible(p.bg_visible)
+, mExpandedBGVisible(p.expanded_bg_visible)
+, mBGColor(p.bg_color)
+, mExpandedBGColor(p.expanded_bg_color)
+, mExpanded(false)
+{
+ LLRect rc = getLocalRect();
+
+ LLScrollContainer::Params scroll_params = p.scroll;
+ scroll_params.rect(rc);
+ mScroll = LLUICtrlFactory::create<LLScrollContainer>(scroll_params);
+ addChild(mScroll);
+
+ LLTextBoxEx::Params textbox_params = p.textbox;
+ textbox_params.rect(rc);
+ mTextBox = LLUICtrlFactory::create<LLTextBoxEx>(textbox_params);
+ mScroll->addChild(mTextBox);
+
+ updateTextBoxRect();
+
+ mTextBox->setCommitCallback(boost::bind(&LLExpandableTextBox::onExpandClicked, this));
+}
+
+void LLExpandableTextBox::draw()
+{
+ if(mBGVisible && !mExpanded)
+ {
+ gl_rect_2d(getLocalRect(), mBGColor.get(), TRUE);
+ }
+ if(mExpandedBGVisible && mExpanded)
+ {
+ gl_rect_2d(getLocalRect(), mExpandedBGColor.get(), TRUE);
+ }
+
+ collapseIfPosChanged();
+
+ LLUICtrl::draw();
+}
+
+void LLExpandableTextBox::collapseIfPosChanged()
+{
+ if(mExpanded)
+ {
+ LLView* parentp = getParent();
+ LLRect parent_rect = parentp->getRect();
+ parentp->localRectToOtherView(parent_rect, &parent_rect, getRootView());
+
+ if(parent_rect.mLeft != mParentRect.mLeft
+ || parent_rect.mTop != mParentRect.mTop)
+ {
+ collapseTextBox();
+ }
+ }
+}
+
+void LLExpandableTextBox::onExpandClicked()
+{
+ expandTextBox();
+}
+
+void LLExpandableTextBox::updateTextBoxRect()
+{
+ LLRect rc = getLocalRect();
+
+ rc.mLeft += mScroll->getBorderWidth();
+ rc.mRight -= mScroll->getBorderWidth();
+ rc.mTop -= mScroll->getBorderWidth();
+ rc.mBottom += mScroll->getBorderWidth();
+
+ mTextBox->reshape(rc.getWidth(), rc.getHeight());
+ mTextBox->setRect(rc);
+}
+
+S32 LLExpandableTextBox::recalculateTextDelta(S32 text_delta)
+{
+ LLRect expanded_rect = getLocalRect();
+ LLView* root_view = getRootView();
+ LLRect window_rect = root_view->getRect();
+
+ LLRect expanded_screen_rect;
+ localRectToOtherView(expanded_rect, &expanded_screen_rect, root_view);
+
+ // don't allow expanded text box bottom go off screen
+ if(expanded_screen_rect.mBottom - text_delta < window_rect.mBottom)
+ {
+ text_delta = expanded_screen_rect.mBottom - window_rect.mBottom;
+ }
+ // show scroll bar if max_height is valid
+ // and expanded size is greater that max_height
+ else if(mMaxHeight > 0 && expanded_rect.getHeight() + text_delta > mMaxHeight)
+ {
+ text_delta = mMaxHeight - expanded_rect.getHeight();
+ }
+
+ return text_delta;
+}
+
+void LLExpandableTextBox::expandTextBox()
+{
+ S32 text_delta = mTextBox->getVerticalTextDelta();
+ text_delta += mTextBox->getVPad() * 2 + mScroll->getBorderWidth() * 2;
+ // no need to expand
+ if(text_delta <= 0)
+ {
+ return;
+ }
+
+ saveCollapsedState();
+
+ LLRect expanded_rect = getLocalRect();
+ LLRect expanded_screen_rect;
+
+ S32 updated_text_delta = recalculateTextDelta(text_delta);
+ // actual expand
+ expanded_rect.mBottom -= updated_text_delta;
+
+ LLRect text_box_rect = mTextBox->getRect();
+
+ // check if we need to show scrollbar
+ if(text_delta != updated_text_delta)
+ {
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+ // disable horizontal scrollbar
+ text_box_rect.mRight -= scrollbar_size;
+ // text box size has changed - redo text wrap
+ mTextBox->setWrappedText(mText, text_box_rect.getWidth());
+ // recalculate text delta since text wrap changed text height
+ text_delta = mTextBox->getVerticalTextDelta() + mTextBox->getVPad() * 2;
+ }
+
+ // expand text
+ text_box_rect.mBottom -= text_delta;
+ mTextBox->reshape(text_box_rect.getWidth(), text_box_rect.getHeight());
+ mTextBox->setRect(text_box_rect);
+
+ // expand text box
+ localRectToOtherView(expanded_rect, &expanded_screen_rect, getParent());
+ reshape(expanded_screen_rect.getWidth(), expanded_screen_rect.getHeight(), FALSE);
+ setRect(expanded_screen_rect);
+
+ setFocus(TRUE);
+ // this lets us receive top_lost event(needed to collapse text box)
+ // it also draws text box above all other ui elements
+ gFocusMgr.setTopCtrl(this);
+
+ mExpanded = true;
+}
+
+void LLExpandableTextBox::collapseTextBox()
+{
+ if(!mExpanded)
+ {
+ return;
+ }
+
+ mExpanded = false;
+
+ reshape(mCollapsedRect.getWidth(), mCollapsedRect.getHeight(), FALSE);
+ setRect(mCollapsedRect);
+
+ updateTextBoxRect();
+
+ mTextBox->setWrappedText(mText);
+ if(gFocusMgr.getTopCtrl() == this)
+ {
+ gFocusMgr.setTopCtrl(NULL);
+ }
+}
+
+void LLExpandableTextBox::onFocusLost()
+{
+ collapseTextBox();
+
+ LLUICtrl::onFocusLost();
+}
+
+void LLExpandableTextBox::onTopLost()
+{
+ collapseTextBox();
+
+ LLUICtrl::onTopLost();
+}
+
+void LLExpandableTextBox::setValue(const LLSD& value)
+{
+ collapseTextBox();
+
+ mText = value.asString();
+ mTextBox->setValue(value);
+}
+
+void LLExpandableTextBox::setText(const std::string& str)
+{
+ collapseTextBox();
+
+ mText = str;
+ mTextBox->setText(str);
+}
+
+void LLExpandableTextBox::saveCollapsedState()
+{
+ mCollapsedRect = getRect();
+
+ mParentRect = getParent()->getRect();
+ // convert parent rect to screen coordinates,
+ // this will allow to track parent's position change
+ getParent()->localRectToOtherView(mParentRect, &mParentRect, getRootView());
+}
diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h
new file mode 100644
index 0000000000..0a5a4c8b75
--- /dev/null
+++ b/indra/newview/llexpandabletextbox.h
@@ -0,0 +1,237 @@
+/**
+ * @file llexpandabletextbox.h
+ * @brief LLExpandableTextBox and related class definitions
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-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_LLEXPANDABLETEXTBOX_H
+#define LL_LLEXPANDABLETEXTBOX_H
+
+#include "lltextbox.h"
+#include "llscrollcontainer.h"
+
+/**
+ * LLExpandableTextBox is a text box control that will show "More" link at end of text
+ * if text doesn't fit into text box. After pressing "More" the text box will expand to show
+ * all text. If text is still too big, a scroll bar will appear inside expanded text box.
+ */
+class LLExpandableTextBox : public LLUICtrl
+{
+protected:
+
+ /**
+ * Extended text box. "More" link will appear at end of text if
+ * text is too long to fit into text box size.
+ */
+ class LLTextBoxEx : public LLTextBox
+ {
+ public:
+ struct Params : public LLInitParam::Block<Params, LLTextBox::Params>
+ {
+ Optional<LLTextBox::Params> expand_textbox;
+
+ Params();
+ };
+
+ /**
+ * Draw text box and "More" link
+ */
+ /*virtual*/ void draw();
+
+ /**
+ * Draws simple text(no urls) line by line, will show or hide "More" link
+ * if needed.
+ */
+ /*virtual*/ void drawText( S32 x, S32 y, const LLWString &text, const LLColor4& color );
+
+ /**
+ * Draws segmented text(with urls) line by line. Will show or hide "More" link
+ * if needed
+ */
+ void drawTextSegments(S32 x, S32 y, const LLWString &text);
+
+ /**
+ * Returns difference between text box height and text height.
+ * Value is positive if text height is greater than text box height.
+ */
+ virtual S32 getVerticalTextDelta();
+
+ /**
+ * Returns text vertical padding
+ */
+ virtual S32 getVPad() { return mVPad; }
+
+ /**
+ * Returns text horizontal padding
+ */
+ virtual S32 getHPad() { return mHPad; }
+
+ /**
+ * Broadcasts "commit" signal if user clicked "More" link
+ */
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+
+ protected:
+
+ LLTextBoxEx(const Params& p);
+ friend class LLUICtrlFactory;
+
+ /**
+ * Shows "More" link
+ */
+ void showExpandText(S32 y);
+
+ /**
+ * Hides "More" link
+ */
+ void hideExpandText();
+
+ /**
+ * Returns cropped line width
+ */
+ S32 getCropTextWidth();
+
+ private:
+
+ LLTextBox* mExpandTextBox;
+ };
+
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLTextBoxEx::Params> textbox;
+
+ Optional<LLScrollContainer::Params> scroll;
+
+ Optional<S32> max_height;
+
+ Optional<bool> bg_visible,
+ expanded_bg_visible;
+
+ Optional<LLUIColor> bg_color,
+ expanded_bg_color;
+
+ Params();
+ };
+
+ /**
+ * Sets text
+ */
+ virtual void setText(const std::string& str);
+
+ /**
+ * Returns text
+ */
+ virtual std::string getText() const { return mText; }
+
+ /**
+ * Sets text
+ */
+ /*virtual*/ void setValue(const LLSD& value);
+
+ /**
+ * Returns text
+ */
+ /*virtual*/ LLSD getValue() const { return mText; }
+
+ /**
+ * Collapses text box on focus_lost event
+ */
+ /*virtual*/ void onFocusLost();
+
+ /**
+ * Collapses text box on top_lost event
+ */
+ /*virtual*/ void onTopLost();
+
+ /**
+ * Draws text box, collapses text box if its expanded and its parent's position changed
+ */
+ /*virtual*/ void draw();
+
+protected:
+
+ LLExpandableTextBox(const Params& p);
+ friend class LLUICtrlFactory;
+
+ /**
+ * Expands text box.
+ * A scroll bar will appear if expanded height is greater than max_height
+ */
+ virtual void expandTextBox();
+
+ /**
+ * Collapses text box.
+ */
+ virtual void collapseTextBox();
+
+ /**
+ * Collapses text box if it is expanded and its parent's position changed
+ */
+ virtual void collapseIfPosChanged();
+
+ /**
+ * Updates text box rect to avoid horizontal scroll bar
+ */
+ virtual void updateTextBoxRect();
+
+ /**
+ * User clicked on "More" link - expand text box
+ */
+ virtual void onExpandClicked();
+
+ /**
+ * Saves collapsed text box's states(rect, parent rect...)
+ */
+ virtual void saveCollapsedState();
+
+ /**
+ * Recalculate text delta considering min_height and window rect.
+ */
+ virtual S32 recalculateTextDelta(S32 text_delta);
+
+protected:
+
+ std::string mText;
+ LLTextBoxEx* mTextBox;
+ LLScrollContainer* mScroll;
+
+ S32 mMaxHeight;
+ LLRect mCollapsedRect;
+ bool mExpanded;
+ LLRect mParentRect;
+
+ bool mBGVisible;
+ bool mExpandedBGVisible;
+ LLUIColor mBGColor;
+ LLUIColor mExpandedBGColor;
+};
+
+#endif //LL_LLEXPANDABLETEXTBOX_H
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 ef71e35254..ea947a5565 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -144,6 +144,18 @@ public:
void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); }
const LLUUID& getLandmarkId() const { return mUrlGetter.getLandmarkId(); }
+ void onMouseEnter(S32 x, S32 y, MASK mask)
+ {
+ if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
+ {
+ LLUICtrl::onMouseEnter(x, y, mask);
+ }
+ else
+ {
+ LLButton::onMouseEnter(x, y, mask);
+ }
+ }
+
protected:
LLFavoriteLandmarkButton(const LLButton::Params& p) : LLButton(p) {}
friend class LLUICtrlFactory;
@@ -278,7 +290,8 @@ struct LLFavoritesSort
};
LLFavoritesBarCtrl::Params::Params()
-: chevron_button_tool_tip("chevron_button_tool_tip")
+: chevron_button_tool_tip("chevron_button_tool_tip"),
+ image_drag_indication("image_drag_indication")
{
}
@@ -287,7 +300,12 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()),
mPopupMenuHandle(),
mInventoryItemsPopupMenuHandle(),
- mChevronButtonToolTip(p.chevron_button_tool_tip)
+ mChevronButtonToolTip(p.chevron_button_tool_tip),
+ mImageDragIndication(p.image_drag_indication),
+ mShowDragMarker(FALSE),
+ mLandingTab(NULL),
+ mLastTab(NULL),
+ mTabsHighlightEnabled(TRUE)
{
// Register callback for menus with current registrar (will be parent panel's registrar)
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Favorites.DoToSelected",
@@ -321,17 +339,49 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
case DAD_LANDMARK:
{
+ /*
+ * add a callback to the end drag event.
+ * the callback will disconnet itself immediately after execution
+ * this is done because LLToolDragAndDrop is a common tool so it shouldn't
+ * be overloaded with redundant callbacks.
+ */
+ if (!mEndDragConnection.connected())
+ {
+ mEndDragConnection = LLToolDragAndDrop::getInstance()->setEndDragCallback(boost::bind(&LLFavoritesBarCtrl::onEndDrag, this));
+ }
+
// Copy the item into the favorites folder (if it's not already there).
LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+ if (LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y)))
+ {
+ setLandingTab(dest);
+ }
+ /*
+ * the condition dest == NULL can be satisfied not only in the case
+ * of dragging to the right from the last tab of the favbar. there is a
+ * small gap between each tab. if the user drags something exactly there
+ * then mLandingTab will be set to NULL and the dragged item will be pushed
+ * to the end of the favorites bar. this is incorrect behavior. that's why
+ * we need an additional check which excludes the case described previously
+ * making sure that the mouse pointer is beyond the last tab.
+ */
+ else if (mLastTab && x >= mLastTab->getRect().mRight)
+ {
+ setLandingTab(NULL);
+ }
+
// check if we are dragging an existing item from the favorites bar
if (item && mDragItemId == item->getUUID())
{
*accept = ACCEPT_YES_SINGLE;
+ showDragMarker(TRUE);
+
if (drop)
{
handleExistingFavoriteDragAndDrop(x, y);
+ showDragMarker(FALSE);
}
}
else
@@ -343,11 +393,14 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
break;
}
- *accept = ACCEPT_YES_COPY_SINGLE;
+ *accept = ACCEPT_YES_COPY_MULTI;
+
+ showDragMarker(TRUE);
if (drop)
{
handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
+ showDragMarker(FALSE);
}
}
}
@@ -361,7 +414,13 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
{
- LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y));
+ LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
+
+ // there is no need to handle if an item was dragged onto itself
+ if (dest && dest->getLandmarkId() == mDragItemId)
+ {
+ return;
+ }
if (dest)
{
@@ -381,14 +440,17 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
menu->setVisible(FALSE);
showDropDownMenu();
}
-
- mDragItemId = LLUUID::null;
- getWindow()->setCursor(UI_CURSOR_ARROW);
}
void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y)
{
- LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y));
+ LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
+
+ // there is no need to handle if an item was dragged onto itself
+ if (dest && dest->getLandmarkId() == mDragItemId)
+ {
+ return;
+ }
if (dest)
{
@@ -458,6 +520,30 @@ void LLFavoritesBarCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
LLUICtrl::reshape(width, height, called_from_parent);
}
+void LLFavoritesBarCtrl::draw()
+{
+ LLUICtrl::draw();
+
+ if (mShowDragMarker)
+ {
+ S32 w = mImageDragIndication->getWidth() / 2;
+ S32 h = mImageDragIndication->getHeight() / 2;
+
+ if (mLandingTab)
+ {
+ // mouse pointer hovers over an existing tab
+ LLRect rect = mLandingTab->getRect();
+ mImageDragIndication->draw(rect.mLeft - w/2, rect.getHeight(), w, h);
+ }
+ else if (mLastTab)
+ {
+ // mouse pointer hovers over the favbar empty space (right to the last tab)
+ LLRect rect = mLastTab->getRect();
+ mImageDragIndication->draw(rect.mRight, rect.getHeight(), w, h);
+ }
+ }
+}
+
LLXMLNodePtr LLFavoritesBarCtrl::getButtonXMLNode()
{
LLXMLNodePtr buttonXMLNode = NULL;
@@ -628,11 +714,15 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite
{
S32 curr_x = buttonHGap;
// Adding buttons
+
+ LLFavoriteLandmarkButton* fav_btn = NULL;
+ mLandingTab = mLastTab = NULL;
+
for(S32 i = mFirstDropDownItem -1, j = 0; i >= 0; i--)
{
LLViewerInventoryItem* item = items.get(j++);
- LLFavoriteLandmarkButton* fav_btn = LLUICtrlFactory::defaultBuilder<LLFavoriteLandmarkButton>(buttonXMLNode, this, NULL);
+ fav_btn = LLUICtrlFactory::defaultBuilder<LLFavoriteLandmarkButton>(buttonXMLNode, this, NULL);
if (NULL == fav_btn)
{
llwarns << "Unable to create button for landmark: " << item->getName() << llendl;
@@ -657,6 +747,8 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite
curr_x += buttonWidth + buttonHGap;
}
+
+ mLastTab = fav_btn;
}
@@ -784,6 +876,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4));
menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
+ menu_item->setLandmarkID(item->getUUID());
// Check whether item name wider than menu
if (menu_item->getNominalWidth() > max_width)
@@ -841,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));
@@ -968,7 +1072,6 @@ void LLFavoritesBarCtrl::pastFromClipboard() const
void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
{
mDragItemId = id;
- mStartDrag = TRUE;
S32 screenX, screenY;
localPointToScreen(x, y, &screenX, &screenY);
@@ -981,9 +1084,18 @@ void LLFavoritesBarCtrl::onButtonMouseUp(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y
mDragItemId = LLUUID::null;
}
+void LLFavoritesBarCtrl::onEndDrag()
+{
+ mEndDragConnection.disconnect();
+
+ showDragMarker(FALSE);
+ mDragItemId = LLUUID::null;
+ LLView::getWindow()->setCursor(UI_CURSOR_ARROW);
+}
+
BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask)
{
- if (mDragItemId != LLUUID::null && mStartDrag)
+ if (mDragItemId != LLUUID::null)
{
S32 screenX, screenY;
localPointToScreen(x, y, &screenX, &screenY);
@@ -994,8 +1106,6 @@ BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask)
DAD_LANDMARK, mDragItemId,
LLToolDragAndDrop::SOURCE_LIBRARY);
- mStartDrag = FALSE;
-
return LLToolDragAndDrop::getInstance()->handleHover(x, y, mask);
}
}
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 4cd92d1a58..97117c3b4a 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -43,6 +43,7 @@ public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional<std::string> chevron_button_tool_tip;
+ Optional<LLUIImage*> image_drag_indication;
Params();
};
@@ -61,10 +62,14 @@ 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);
+ virtual void draw();
+
+ void showDragMarker(BOOL show) { mShowDragMarker = show; }
+ void setLandingTab(LLUICtrl* tab) { mLandingTab = tab; }
protected:
void updateButtons(U32 bar_width);
@@ -78,6 +83,8 @@ protected:
void onButtonMouseDown(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
void onButtonMouseUp(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
+ void onEndDrag();
+
void doToSelected(const LLSD& userdata);
BOOL isClipboardPasteable() const;
void pastFromClipboard() const;
@@ -98,6 +105,7 @@ protected:
LLRect mChevronRect;
std::string mChevronButtonToolTip;
+ LLUIImage* mImageDragIndication;
private:
/*
@@ -136,10 +144,16 @@ private:
// finds an item by it's UUID in the items array
LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
- BOOL mSkipUpdate;
- BOOL mStartDrag;
+ BOOL mShowDragMarker;
+ LLUICtrl* mLandingTab;
+ LLUICtrl* mLastTab;
+
LLUUID mDragItemId;
LLInventoryModel::item_array_t mItems;
+
+ BOOL mTabsHighlightEnabled;
+
+ boost::signals2::connection mEndDragConnection;
};
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/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index f4c4f38008..0511ec1063 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -88,7 +88,6 @@ void LLFloaterCamera::update()
{
ECameraControlMode mode = determineMode();
if (mode != mCurrMode) setMode(mode);
- updatePosition();
show_tip(mMode2TipType[mode], this);
}
@@ -122,48 +121,20 @@ LLFloaterCamera* LLFloaterCamera::findInstance()
return LLFloaterReg::findTypedInstance<LLFloaterCamera>("camera");
}
-/*static*/
-void LLFloaterCamera::onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param)
-{
- std::string name = param.asString();
-
- if ("rear_view" == name)
- {
- LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_REAR, ctrl);
- gAgent.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
- }
- else if ("group_view" == name)
- {
- LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_GROUP);
- gAgent.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW);
- }
- else if ("front_view" == name)
- {
- LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_FRONT);
- gAgent.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW);
- }
-
-}
-
void LLFloaterCamera::onOpen(const LLSD& key)
{
- updatePosition();
-}
-
-void LLFloaterCamera::updatePosition()
-{
- LLBottomTray* tray = LLBottomTray::getInstance();
- if (!tray) return;
+ LLButton *anchor_panel = LLBottomTray::getInstance()->getChild<LLButton>("camera_btn");
- LLButton* camera_button = tray->getChild<LLButton>("camera_btn");
+ setDockControl(new LLDockControl(
+ anchor_panel, this,
+ getDockTongue(), LLDockControl::TOP));
- //align centers of a button and a floater
- S32 x = camera_button->calcScreenRect().getCenterX() - getRect().getWidth()/2;
- setOrigin(x, 0);
+ show_tip(mMode2TipType[mCurrMode], this);
}
+
LLFloaterCamera::LLFloaterCamera(const LLSD& val)
-: LLFloater(val),
+: LLDockableFloater(NULL, false, val),
mCurrMode(CAMERA_CTRL_MODE_ORBIT),
mPrevMode(CAMERA_CTRL_MODE_ORBIT)
{
@@ -187,7 +158,7 @@ BOOL LLFloaterCamera::postBuild()
update();
- return TRUE;
+ return LLDockableFloater::postBuild();
}
ECameraControlMode LLFloaterCamera::determineMode()
@@ -311,7 +282,8 @@ void LLFloaterCamera::updateState()
LLRect controls_rect;
if (childGetRect(CONTROLS, controls_rect))
{
- static S32 height = controls_rect.getHeight();
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+ static S32 height = controls_rect.getHeight() - floater_header_size;
S32 newHeight = rect.getHeight();
if (showControls)
@@ -330,3 +302,46 @@ void LLFloaterCamera::updateState()
}
}
+//-------------LLFloaterCameraPresets------------------------
+
+LLFloaterCameraPresets::LLFloaterCameraPresets(const LLSD& key):
+LLDockableFloater(NULL, false, key)
+{}
+
+BOOL LLFloaterCameraPresets::postBuild()
+{
+ setIsChrome(TRUE);
+
+ //build dockTongue
+ LLDockableFloater::postBuild();
+
+ LLButton *anchor_btn = LLBottomTray::getInstance()->getChild<LLButton>("camera_presets_btn");
+
+ setDockControl(new LLDockControl(
+ anchor_btn, this,
+ getDockTongue(), LLDockControl::TOP));
+ return TRUE;
+}
+
+/*static*/
+void LLFloaterCameraPresets::onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param)
+{
+ std::string name = param.asString();
+
+ if ("rear_view" == name)
+ {
+ LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_REAR, ctrl);
+ gAgent.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
+ }
+ else if ("group_view" == name)
+ {
+ LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_GROUP);
+ gAgent.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW);
+ }
+ else if ("front_view" == name)
+ {
+ LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_FRONT);
+ gAgent.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW);
+ }
+
+}
diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h
index 1181c443bf..020cae7e82 100644
--- a/indra/newview/llfloatercamera.h
+++ b/indra/newview/llfloatercamera.h
@@ -33,7 +33,7 @@
#ifndef LLFLOATERCAMERA_H
#define LLFLOATERCAMERA_H
-#include "llfloater.h"
+#include "lldockablefloater.h"
#include "llfirsttimetipmanager.h"
@@ -51,7 +51,7 @@ enum ECameraControlMode
};
class LLFloaterCamera
- : public LLFloater
+ : public LLDockableFloater
{
friend class LLFloaterReg;
@@ -70,14 +70,8 @@ public:
static void updateIfNotInAvatarViewMode();
- static void onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param);
-
virtual void onOpen(const LLSD& key);
- // *HACK: due to hard enough to have this control aligned with "Camera" button while resizing
- // let update its position in each frame
- /*virtual*/ void draw(){updatePosition(); LLFloater::draw();}
-
LLJoystickCameraRotate* mRotate;
LLJoystickCameraZoom* mZoom;
LLJoystickCameraTrack* mTrack;
@@ -113,9 +107,6 @@ private:
void assignButton2Mode(ECameraControlMode mode, const std::string& button_name);
void initMode2TipTypeMap();
- /*Updates position of the floater to be center aligned with "Camera" button.*/
- void updatePosition();
-
ECameraControlMode mPrevMode;
ECameraControlMode mCurrMode;
@@ -124,4 +115,15 @@ private:
};
+class LLFloaterCameraPresets : public LLDockableFloater
+{
+ friend class LLFloaterReg;
+public:
+ static void onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param);
+private:
+ LLFloaterCameraPresets(const LLSD&);
+ ~LLFloaterCameraPresets(){}
+ /*virtual*/ BOOL postBuild();
+
+};
#endif
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 c197c78a41..57c043a1e0 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -102,6 +102,7 @@
#include "llboost.h"
#include "llviewermedia.h"
#include "llpluginclassmedia.h"
+#include "llteleporthistorystorage.h"
#include <boost/regex.hpp>
@@ -194,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;
}
@@ -221,6 +222,9 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response
LLSearchHistory::getInstance()->save();
LLSearchComboBox* search_ctrl = LLNavigationBar::getInstance()->getChild<LLSearchComboBox>("search_combo_box");
search_ctrl->clearHistory();
+
+ LLTeleportHistoryStorage::getInstance()->purgeItems();
+ LLTeleportHistoryStorage::getInstance()->save();
}
return false;
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 cddc67cb0a..905857f393 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -35,24 +35,80 @@
#include "llgrouplist.h"
// libs
+#include "llbutton.h"
+#include "lliconctrl.h"
+#include "lltextbox.h"
#include "lltrans.h"
// newview
#include "llagent.h"
+#include "llgroupactions.h"
+#include "llviewercontrol.h" // for gSavedSettings
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
+S32 LLGroupListItem::sIconWidth = 0;
+
+class LLGroupComparator : public LLFlatListView::ItemComparator
+{
+public:
+ /** Returns true if item1 < item2, false otherwise */
+ /*virtual*/ bool compare(const LLPanel* item1, const LLPanel* item2) const
+ {
+ std::string name1 = static_cast<const LLGroupListItem*>(item1)->getGroupName();
+ std::string name2 = static_cast<const LLGroupListItem*>(item2)->getGroupName();
+
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
+
+ return name1 < name2;
+ }
+};
+
+static const LLGroupComparator GROUP_COMPARATOR;
LLGroupList::Params::Params()
{
- // Prevent the active group from being always first in the list.
- online_go_first = false;
+
}
LLGroupList::LLGroupList(const Params& p)
-: LLAvatarList(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
// display a context menu appropriate for a list of group names
- setContextMenu(LLScrollListCtrl::MENU_GROUP);
+// setContextMenu(LLScrollListCtrl::MENU_GROUP);
+
+ // Set default sort order.
+ 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)
@@ -61,38 +117,201 @@ static bool findInsensitive(std::string haystack, const std::string& needle_uppe
return haystack.find(needle_upper) != std::string::npos;
}
-BOOL LLGroupList::update(const std::string& name_filter)
+void LLGroupList::refresh()
{
- LLCtrlListInterface *group_list = getListInterface();
const LLUUID& highlight_id = gAgent.getGroupID();
S32 count = gAgent.mGroups.count();
LLUUID id;
+ bool have_filter = !mNameFilter.empty();
- group_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ clear();
for(S32 i = 0; i < count; ++i)
{
- // *TODO: check powers mask?
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;
- addItem(id, group_data.mName, highlight_id == id, ADD_BOTTOM); // ADD_SORTED can only sort by first column anyway
+ addNewItem(id, group_data.mName, group_data.mInsigniaID, highlight_id == id, ADD_BOTTOM);
}
- // Force sorting the list.
- updateSort();
+ // Sort the list.
+ sort();
// add "none" to list at top
{
std::string loc_none = LLTrans::getString("GroupsNone");
- if (name_filter == LLStringUtil::null || findInsensitive(loc_none, name_filter))
- addItem(LLUUID::null, loc_none, highlight_id.isNull(), ADD_TOP);
+ if (have_filter || findInsensitive(loc_none, mNameFilter))
+ addNewItem(LLUUID::null, loc_none, LLUUID::null, highlight_id.isNull(), ADD_TOP);
+ }
- // Prevent the "none" item from being sorted.
- setNeedsSort(false);
+ selectItemByUUID(highlight_id);
+
+ setDirty(false);
+ onCommit();
+}
+
+void LLGroupList::toggleIcons()
+{
+ // Save the new value for new items to use.
+ mShowIcons = !mShowIcons;
+ gSavedSettings.setBOOL("GroupListShowIcons", mShowIcons);
+
+ // Show/hide icons for all existing items.
+ std::vector<LLPanel*> items;
+ getItems(items);
+ for( std::vector<LLPanel*>::const_iterator it = items.begin(); it != items.end(); it++)
+ {
+ static_cast<LLGroupListItem*>(*it)->setGroupIconVisible(mShowIcons);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE Section
+//////////////////////////////////////////////////////////////////////////
+
+void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, BOOL is_bold, EAddPosition pos)
+{
+ LLGroupListItem* item = new LLGroupListItem();
+
+ item->setName(name);
+ item->setGroupID(id);
+ item->setGroupIconID(icon_id);
+// item->setContextMenu(mContextMenu);
+
+ item->childSetVisible("info_btn", false);
+ item->setGroupIconVisible(mShowIcons);
+
+ addItem(item, id, pos);
+
+// 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;
}
- group_list->selectByValue(highlight_id);
+ return false;
+}
+
+/************************************************************************/
+/* LLGroupListItem implementation */
+/************************************************************************/
+
+LLGroupListItem::LLGroupListItem()
+: LLPanel(),
+mGroupIcon(NULL),
+mGroupNameBox(NULL),
+mInfoBtn(NULL),
+//mContextMenu(NULL), //TODO:
+mGroupID(LLUUID::null)
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_list_item.xml");
+
+ // Remember group icon width including its padding from the name text box,
+ // so that we can hide and show the icon again later.
+ if (!sIconWidth)
+ {
+ sIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
+ }
+}
+
+//virtual
+BOOL LLGroupListItem::postBuild()
+{
+ mGroupIcon = getChild<LLIconCtrl>("group_icon");
+ mGroupNameBox = getChild<LLTextBox>("group_name");
+
+ mInfoBtn = getChild<LLButton>("info_btn");
+ mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this));
+
return TRUE;
}
+
+//virtual
+void LLGroupListItem::setValue( const LLSD& value )
+{
+ if (!value.isMap()) return;
+ if (!value.has("selected")) return;
+ childSetVisible("selected_icon", value["selected"]);
+}
+
+void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ childSetVisible("hovered_icon", true);
+ if (mGroupID.notNull()) // don't show the info button for the "none" group
+ mInfoBtn->setVisible(true);
+
+ LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ childSetVisible("hovered_icon", false);
+ mInfoBtn->setVisible(false);
+
+ LLPanel::onMouseLeave(x, y, mask);
+}
+
+void LLGroupListItem::setName(const std::string& name)
+{
+ mGroupName = name;
+ mGroupNameBox->setValue(name);
+ mGroupNameBox->setToolTip(name);
+}
+
+void LLGroupListItem::setGroupID(const LLUUID& group_id)
+{
+ mGroupID = group_id;
+ setActive(group_id == gAgent.getGroupID());
+}
+
+void LLGroupListItem::setGroupIconID(const LLUUID& group_icon_id)
+{
+ if (group_icon_id.notNull())
+ {
+ mGroupIcon->setValue(group_icon_id);
+ }
+}
+
+void LLGroupListItem::setGroupIconVisible(bool visible)
+{
+ // Already done? Then do nothing.
+ if (mGroupIcon->getVisible() == (BOOL)visible)
+ return;
+
+ // Show/hide the group icon.
+ mGroupIcon->setVisible(visible);
+
+ // Move the group name horizontally by icon size + its distance from the group name.
+ LLRect name_rect = mGroupNameBox->getRect();
+ name_rect.mLeft += visible ? sIconWidth : -sIconWidth;
+ mGroupNameBox->setRect(name_rect);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Private Section
+//////////////////////////////////////////////////////////////////////////
+void LLGroupListItem::setActive(bool active)
+{
+ // Active group should be bold.
+ LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
+
+ // *NOTE dzaporozhan
+ // On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font
+ // is predefined as bold (SansSerifSmallBold, for example)
+ new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL);
+ mGroupNameBox->setFont(LLFontGL::getFont(new_desc));
+}
+
+void LLGroupListItem::onInfoBtnClick()
+{
+ LLGroupActions::show(mGroupID);
+}
+//EOF
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index e893313f4b..9c3ab88901 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -33,22 +33,79 @@
#ifndef LL_LLGROUPLIST_H
#define LL_LLGROUPLIST_H
-#include <llscrolllistctrl.h>
+#include "llevent.h"
+#include "llflatlistview.h"
+#include "llpanel.h"
+#include "llpointer.h"
-#include "llavatarlist.h"
-
-// *TODO: derive from ListView when it's ready.
-class LLGroupList: public LLAvatarList
+/**
+ * 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:
- struct Params : public LLInitParam::Block<Params, LLAvatarList::Params>
+ struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
{
Params();
};
- LLGroupList(const Params&);
- BOOL update(const std::string& name_filter = LLStringUtil::null);
+ LLGroupList(const Params& p);
+ 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;
+class LLIconCtrl;
+class LLTextBox;
+
+class LLGroupListItem : public LLPanel
+{
+public:
+ LLGroupListItem();
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void setValue(const LLSD& value);
+ void onMouseEnter(S32 x, S32 y, MASK mask);
+ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+ const LLUUID& getGroupID() const { return mGroupID; }
+ const std::string& getGroupName() const { return mGroupName; }
+
+ void setName(const std::string& name);
+ void setGroupID(const LLUUID& group_id);
+ void setGroupIconID(const LLUUID& group_icon_id);
+ void setGroupIconVisible(bool visible);
+
+private:
+ void setActive(bool active);
+ void onInfoBtnClick();
+
+ LLTextBox* mGroupNameBox;
+ LLUUID mGroupID;
+ LLIconCtrl* mGroupIcon;
+ LLButton* mInfoBtn;
+
+ std::string mGroupName;
+
+ static S32 sIconWidth; // icon width + padding
+};
#endif // LL_LLGROUPLIST_H
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
new file mode 100644
index 0000000000..d0be581f6d
--- /dev/null
+++ b/indra/newview/llimfloater.cpp
@@ -0,0 +1,421 @@
+/**
+ * @file llimfloater.cpp
+ * @brief LLIMFloater class definition
+ *
+ * $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 "llimfloater.h"
+
+#include "llagent.h"
+#include "llappviewer.h"
+#include "llbutton.h"
+#include "llbottomtray.h"
+#include "llchannelmanager.h"
+#include "llchiclet.h"
+#include "llfloaterreg.h"
+#include "llimview.h"
+#include "lllineeditor.h"
+#include "llpanelimcontrolpanel.h"
+#include "llscreenchannel.h"
+#include "lltrans.h"
+#include "llviewertexteditor.h"
+#include "llviewerwindow.h"
+#include "lltransientfloatermgr.h"
+
+
+
+LLIMFloater::LLIMFloater(const LLUUID& session_id)
+ : LLDockableFloater(NULL, session_id),
+ mControlPanel(NULL),
+ mSessionID(session_id),
+ mLastMessageIndex(-1),
+ mLastFromName(),
+ mDialog(IM_NOTHING_SPECIAL),
+ mHistoryEditor(NULL),
+ mInputEditor(NULL),
+ mPositioned(false)
+{
+ EInstantMessage type = LLIMModel::getInstance()->getType(session_id);
+ if(IM_COUNT != type)
+ {
+ mDialog = type;
+
+ 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);
+ }
+ }
+
+ 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){
+
+ if (data["num_unread"].asInteger() > 0)
+ {
+ LLUUID session_id = data["session_id"].asUUID();
+
+ LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+ if (floater == NULL)
+ {
+ llwarns << "new_im_callback for non-existent session_id " << session_id << llendl;
+ return;
+ }
+
+ // update if visible, otherwise will be updated when opened
+ if (floater->getVisible())
+ {
+ floater->updateMessages();
+ }
+ }
+}
+
+void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
+{
+ LLIMFloater* self = (LLIMFloater*) userdata;
+ self->sendMsg();
+}
+
+void LLIMFloater::sendMsg()
+{
+ if (!gAgent.isGodlike()
+ && (mDialog == IM_NOTHING_SPECIAL)
+ && mOtherParticipantUUID.isNull())
+ {
+ llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
+ return;
+ }
+
+ if (mInputEditor)
+ {
+ LLWString text = mInputEditor->getConvertedText();
+ if(!text.empty())
+ {
+ // Truncate and convert to UTF8 for transport
+ std::string utf8_text = wstring_to_utf8str(text);
+ utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
+
+ LLIMModel::sendMessage(utf8_text,
+ mSessionID,
+ mOtherParticipantUUID,
+ mDialog);
+
+ mInputEditor->setText(LLStringUtil::null);
+
+ updateMessages();
+ }
+ }
+}
+
+
+
+LLIMFloater::~LLIMFloater()
+{
+ LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
+}
+
+//virtual
+BOOL LLIMFloater::postBuild()
+{
+ const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
+ if (other_party_id.notNull())
+ {
+ mOtherParticipantUUID = other_party_id;
+ mControlPanel->setID(mOtherParticipantUUID);
+ }
+
+ LLButton* slide_left = getChild<LLButton>("slide_left_btn");
+ slide_left->setVisible(mControlPanel->getVisible());
+ slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
+
+ LLButton* slide_right = getChild<LLButton>("slide_right_btn");
+ slide_right->setVisible(!mControlPanel->getVisible());
+ slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
+
+ mInputEditor = getChild<LLLineEditor>("chat_editor");
+ mInputEditor->setMaxTextLength(1023);
+ // enable line history support for instant message bar
+ mInputEditor->setEnableLineHistory(TRUE);
+
+ mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
+ mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
+ mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
+ mInputEditor->setCommitOnFocusLost( FALSE );
+ mInputEditor->setRevertOnEsc( FALSE );
+ mInputEditor->setReplaceNewlinesWithSpaces( FALSE );
+
+ childSetCommitCallback("chat_editor", onSendMsg, this);
+
+ mHistoryEditor = getChild<LLViewerTextEditor>("im_text");
+ mHistoryEditor->setParseHTML(TRUE);
+
+ setTitle(LLIMModel::instance().getName(mSessionID));
+ setDocked(true);
+
+ return LLDockableFloater::postBuild();
+}
+
+
+
+// static
+void* LLIMFloater::createPanelIMControl(void* userdata)
+{
+ LLIMFloater *self = (LLIMFloater*)userdata;
+ self->mControlPanel = new LLPanelIMControlPanel();
+ self->mControlPanel->setXMLFilename("panel_im_control_panel.xml");
+ return self->mControlPanel;
+}
+
+
+// static
+void* LLIMFloater::createPanelGroupControl(void* userdata)
+{
+ LLIMFloater *self = (LLIMFloater*)userdata;
+ self->mControlPanel = new LLPanelGroupControlPanel();
+ self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
+ return self->mControlPanel;
+}
+
+void LLIMFloater::onSlide()
+{
+ LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
+ im_control_panel->setVisible(!im_control_panel->getVisible());
+
+ getChild<LLButton>("slide_left_btn")->setVisible(im_control_panel->getVisible());
+ getChild<LLButton>("slide_right_btn")->setVisible(!im_control_panel->getVisible());
+}
+
+//static
+LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
+{
+ //hide all
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+ iter != inst_list.end(); ++iter)
+ {
+ LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
+ if (floater && floater->isDocked())
+ {
+ floater->setVisible(false);
+ }
+ }
+
+ LLIMFloater* floater = LLFloaterReg::showTypedInstance<LLIMFloater>("impanel", session_id);
+
+ floater->updateMessages();
+ floater->mInputEditor->setFocus(TRUE);
+
+ if (floater->getDockControl() == NULL)
+ {
+ LLChiclet* chiclet =
+ LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(
+ session_id);
+ if (chiclet == NULL)
+ {
+ llerror("Dock chiclet for LLIMFloater doesn't exists", 0);
+ }
+ else
+ {
+ LLBottomTray::getInstance()->getChicletPanel()->scrollToChiclet(chiclet);
+ }
+
+ floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
+ LLDockControl::TOP, boost::bind(&LLIMFloater::getAllowedRect, floater, _1)));
+ }
+
+ return floater;
+}
+
+void LLIMFloater::getAllowedRect(LLRect& rect)
+{
+ rect = gViewerWindow->getWorldViewRect();
+}
+
+void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
+{
+ // update notification channel state
+ 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
+ if(channel)
+ {
+ channel->updateShowToastsState();
+ }
+}
+
+void LLIMFloater::setVisible(BOOL visible)
+{
+ LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
+ (LLNotificationsUI::LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+ LLDockableFloater::setVisible(visible);
+
+ // update notification channel state
+ if(channel)
+ {
+ channel->updateShowToastsState();
+ }
+}
+
+//static
+bool LLIMFloater::toggle(const LLUUID& session_id)
+{
+ LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+ if (floater && floater->getVisible())
+ {
+ // clicking on chiclet to close floater just hides it to maintain existing
+ // scroll/text entry state
+ floater->setVisible(false);
+ return false;
+ }
+ else
+ {
+ // ensure the list of messages is updated when floater is made visible
+ show(session_id);
+ // update number of unread notifications in the SysWell
+ LLBottomTray::getInstance()->getSysWell()->updateUreadIMNotifications();
+ return true;
+ }
+}
+
+void LLIMFloater::updateMessages()
+{
+ std::list<LLSD> messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1);
+ std::string agent_name;
+
+ gCacheName->getFullName(gAgentID, agent_name);
+
+ if (messages.size())
+ {
+ LLUIColor divider_color = LLUIColorTable::instance().getColor("LtGray_50");
+ LLUIColor chat_color = LLUIColorTable::instance().getColor("IMChatColor");
+
+ std::ostringstream message;
+ std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
+ std::list<LLSD>::const_reverse_iterator iter_end = messages.rend();
+ for (; iter != iter_end; ++iter)
+ {
+ LLSD msg = *iter;
+
+ const bool prepend_newline = true;
+ std::string from = msg["from"].asString();
+ if (from == agent_name)
+ from = LLTrans::getString("You");
+ if (mLastFromName != from)
+ {
+ message << from << " ----- " << msg["time"].asString();
+ mHistoryEditor->appendColoredText(message.str(), false,
+ prepend_newline, divider_color);
+ message.str("");
+ mLastFromName = from;
+ }
+
+ message << msg["message"].asString();
+ mHistoryEditor->appendColoredText(message.str(), false,
+ prepend_newline, chat_color);
+ message.str("");
+
+ mLastMessageIndex = msg["index"].asInteger();
+ }
+
+ mHistoryEditor->setCursorAndScrollToEnd();
+ }
+}
+
+// static
+void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
+{
+ LLIMFloater* self= (LLIMFloater*) userdata;
+
+ //in disconnected state IM input editor should be disabled
+ self->mInputEditor->setEnabled(!gDisconnected);
+
+ self->mHistoryEditor->setCursorAndScrollToEnd();
+}
+
+// static
+void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
+{
+ LLIMFloater* self = (LLIMFloater*) userdata;
+ self->setTyping(FALSE);
+}
+
+// static
+void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
+{
+ LLIMFloater* self = (LLIMFloater*)userdata;
+ std::string text = self->mInputEditor->getText();
+ if (!text.empty())
+ {
+ self->setTyping(TRUE);
+ }
+ else
+ {
+ // Deleting all text counts as stopping typing.
+ self->setTyping(FALSE);
+ }
+}
+
+
+//just a stub for now
+void LLIMFloater::setTyping(BOOL typing)
+{
+}
+
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
new file mode 100644
index 0000000000..a183212f04
--- /dev/null
+++ b/indra/newview/llimfloater.h
@@ -0,0 +1,114 @@
+/**
+ * @file llimfloater.h
+ * @brief LLIMFloater class definition
+ *
+ * $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_IMFLOATER_H
+#define LL_IMFLOATER_H
+
+#include "lldockablefloater.h"
+
+class LLLineEditor;
+class LLPanelChatControlPanel;
+class LLViewerTextEditor;
+
+
+/**
+ * Individual IM window that appears at the bottom of the screen,
+ * optionally "docked" to the bottom tray.
+ */
+class LLIMFloater : public LLDockableFloater
+{
+public:
+ LLIMFloater(const LLUUID& session_id);
+
+ virtual ~LLIMFloater();
+
+ // LLView overrides
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void setVisible(BOOL visible);
+
+ // 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);
+
+ // Toggle panel specified by session_id
+ // Returns true iff panel became visible
+ static bool toggle(const LLUUID& session_id);
+
+ // get new messages from LLIMModel
+ void updateMessages();
+ static void onSendMsg( LLUICtrl*, void*);
+ void sendMsg();
+
+ // callback for LLIMModel on new messages
+ // route to specific floater if it is visible
+ static void newIMCallback(const LLSD& data);
+
+ // called when docked floater's position has been set by chiclet
+ void setPositioned(bool b) { mPositioned = b; };
+
+ // handler for a CLOSE signal
+ void onClose();
+
+
+private:
+
+ static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
+ static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
+ static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
+ void setTyping(BOOL typing);
+ void onSlide();
+ static void* createPanelIMControl(void* userdata);
+ static void* createPanelGroupControl(void* userdata);
+ // gets a rect that bounds possible positions for the LLIMFloater on a screen (EXT-1111)
+ void getAllowedRect(LLRect& rect);
+
+ LLPanelChatControlPanel* mControlPanel;
+ LLUUID mSessionID;
+ S32 mLastMessageIndex;
+
+ // username of last user who added text to this conversation, used to
+ // suppress duplicate username divider bars
+ std::string mLastFromName;
+
+ EInstantMessage mDialog;
+ LLUUID mOtherParticipantUUID;
+ LLViewerTextEditor* mHistoryEditor;
+ LLLineEditor* mInputEditor;
+ bool mPositioned;
+};
+
+
+#endif // LL_IMFLOATER_H
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index a47477c446..74971f3fd8 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -36,29 +36,18 @@
#include "llnotificationhandler.h"
#include "llagentdata.h"
-#include "llbottomtray.h"
-#include "llviewercontrol.h"
#include "lltoastimpanel.h"
+#include "llviewerwindow.h"
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLIMHandler::LLIMHandler()
+LLIMHandler::LLIMHandler(e_notification_type type, const LLSD& id)
{
-
- // getting a Chiclet and creating params for a channel
- LLBottomTray* tray = LLBottomTray::getInstance();
- mChiclet = tray->getSysWell();
-
- LLChannelManager::Params p;
- // *TODO: createNotificationChannel method
- p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID"));
- p.channel_right_bound = tray->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
- p.channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+ mType = type;
// Getting a Channel for our notifications
- mChannel = LLChannelManager::getInstance()->createChannel(p);
-
+ mChannel = LLChannelManager::getInstance()->createNotificationChannel();
}
//--------------------------------------------------------------------------
@@ -67,12 +56,31 @@ LLIMHandler::~LLIMHandler()
}
//--------------------------------------------------------------------------
-void LLIMHandler::processNotification(const LLSD& notify)
+void LLIMHandler::initChannel()
+{
+ S32 channel_right_bound = gViewerWindow->getWorldViewRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+ mChannel->init(channel_right_bound - channel_width, channel_right_bound);
+}
+
+//--------------------------------------------------------------------------
+bool LLIMHandler::processNotification(const LLSD& notify)
{
+ if(!mChannel)
+ {
+ return false;
+ }
+
LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
if(!notification)
- return;
+ return false;
+
+ // arrange a channel on a screen
+ if(!mChannel->getVisible())
+ {
+ initChannel();
+ }
if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
{
@@ -95,40 +103,33 @@ void LLIMHandler::processNotification(const LLSD& notify)
LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
LLToast::Params p;
- p.id = notification->getID();
+ p.notif_id = notification->getID();
+ p.session_id = im_p.session_id;
p.notification = notification;
p.panel = im_box;
p.can_be_stored = false;
- p.on_toast_destroy = boost::bind(&LLIMHandler::onToastDestroy, this, _1);
- mChannel->addToast(p);
-
+ p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
- static_cast<LLNotificationChiclet*>(mChiclet)->updateUreadIMNotifications();
+ // send a signal to the counter manager;
+ mNewNotificationSignal();
}
else if (notify["sigtype"].asString() == "delete")
{
mChannel->killToastByNotificationID(notification->getID());
}
+ return true;
}
//--------------------------------------------------------------------------
-void LLIMHandler::onToastDestroy(LLToast* toast)
-{
- toast->closeFloater();
- static_cast<LLNotificationChiclet*>(mChiclet)->updateUreadIMNotifications();
-}
-
-//--------------------------------------------------------------------------
-void LLIMHandler::onChicletClick(void)
+void LLIMHandler::onDeleteToast(LLToast* toast)
{
+ // send a signal to the counter manager
+ mDelNotificationSignal();
}
//--------------------------------------------------------------------------
-void LLIMHandler::onChicletClose(void)
-{
-}
-
-//--------------------------------------------------------------------------
-
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 0efe9b9849..abd3cd4def 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -48,6 +48,7 @@
#include "llbutton.h"
#include "llbottomtray.h"
#include "llcallingcard.h"
+#include "llchannelmanager.h"
#include "llchat.h"
#include "llchiclet.h"
#include "llconsole.h"
@@ -81,6 +82,7 @@
#include "llhttpclient.h"
#include "llmutelist.h"
#include "llstylemap.h"
+#include "llappviewer.h"
//
// Constants
@@ -938,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),
@@ -954,7 +955,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
mTextIMPossible(TRUE),
mProfileButtonEnabled(TRUE),
mCallBackEnabled(TRUE),
- mSpeakers(NULL),
mSpeakerPanel(NULL),
mFirstKeystrokeTimer(),
mLastKeystrokeTimer()
@@ -965,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);
@@ -977,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:
@@ -996,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;
@@ -1005,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);
@@ -1056,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()
@@ -1097,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 );
@@ -1153,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;
}
@@ -1199,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);
@@ -1228,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;
@@ -1264,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();
}
@@ -1404,12 +1367,6 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
{
mNumUnreadMessages++;
}
-
- if (source != LLUUID::null)
- {
- mSpeakers->speakerChatted(source);
- mSpeakers->setSpeakerTyping(source, FALSE);
- }
}
@@ -1590,7 +1547,7 @@ void LLFloaterIMPanel::onClickStartCall(void* userdata)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
- self->mVoiceChannel->activate();
+ LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->activate();
}
// static
@@ -1598,7 +1555,7 @@ void LLFloaterIMPanel::onClickEndCall(void* userdata)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
- self->getVoiceChannel()->deactivate();
+ LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->deactivate();
}
// static
@@ -1672,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);
@@ -1724,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 (
@@ -1752,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
@@ -1791,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
@@ -1805,7 +1753,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
mSentTypingState = FALSE;
}
- mSpeakers->setSpeakerTyping(gAgent.getID(), TRUE);
+ speaker_mgr->setSpeakerTyping(gAgent.getID(), TRUE);
}
else
{
@@ -1815,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;
@@ -1875,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);
}
}
}
@@ -1986,318 +1934,4 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const
}
return false;
}
-
-
-LLIMFloater::LLIMFloater(const LLUUID& session_id)
- : LLDockableFloater(NULL, session_id),
- mControlPanel(NULL),
- mSessionID(session_id),
- mLastMessageIndex(-1),
- mLastFromName(),
- mDialog(IM_NOTHING_SPECIAL),
- mHistoryEditor(NULL),
- mInputEditor(NULL),
- mPositioned(false)
-{
- LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
- if(session)
- {
- mDialog = session->mType;
- }
-
- if (mDialog == IM_NOTHING_SPECIAL)
- {
- 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");
-}
-
-/* static */
-void LLIMFloater::newIMCallback(const LLSD& data){
-
- if (data["num_unread"].asInteger() > 0)
- {
- LLUUID session_id = data["session_id"].asUUID();
-
- LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
- if (floater == NULL)
- {
- llwarns << "new_im_callback for non-existent session_id " << session_id << llendl;
- return;
- }
-
- // update if visible, otherwise will be updated when opened
- if (floater->getVisible())
- {
- floater->updateMessages();
- }
- }
-}
-
-void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
-{
- LLIMFloater* self = (LLIMFloater*) userdata;
- self->sendMsg();
-}
-
-void LLIMFloater::sendMsg()
-{
- if (!gAgent.isGodlike()
- && (mDialog == IM_NOTHING_SPECIAL)
- && mOtherParticipantUUID.isNull())
- {
- llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
- return;
- }
-
- if (mInputEditor)
- {
- LLWString text = mInputEditor->getConvertedText();
- if(!text.empty())
- {
- // Truncate and convert to UTF8 for transport
- std::string utf8_text = wstring_to_utf8str(text);
- utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
-
- LLIMModel::sendMessage(utf8_text,
- mSessionID,
- mOtherParticipantUUID,
- mDialog);
-
- mInputEditor->setText(LLStringUtil::null);
-
- updateMessages();
- }
- }
-}
-
-
-
-LLIMFloater::~LLIMFloater()
-{
-}
-
-//virtual
-BOOL LLIMFloater::postBuild()
-{
- LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
- if(session)
- {
- mOtherParticipantUUID = session->mOtherParticipantID;
- mControlPanel->setID(session->mOtherParticipantID);
- }
-
- LLButton* slide_left = getChild<LLButton>("slide_left_btn");
- slide_left->setVisible(mControlPanel->getVisible());
- slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
-
- LLButton* slide_right = getChild<LLButton>("slide_right_btn");
- slide_right->setVisible(!mControlPanel->getVisible());
- slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
-
- mInputEditor = getChild<LLLineEditor>("chat_editor");
- mInputEditor->setMaxTextLength(1023);
- // enable line history support for instant message bar
- mInputEditor->setEnableLineHistory(TRUE);
-
- mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
- mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
- mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
- mInputEditor->setCommitOnFocusLost( FALSE );
- mInputEditor->setRevertOnEsc( FALSE );
- mInputEditor->setReplaceNewlinesWithSpaces( FALSE );
-
- childSetCommitCallback("chat_editor", onSendMsg, this);
-
- mHistoryEditor = getChild<LLViewerTextEditor>("im_text");
- mHistoryEditor->setParseHTML(TRUE);
-
- setTitle(LLIMModel::instance().getName(mSessionID));
- setDocked(true);
-
- return LLDockableFloater::postBuild();
-}
-
-
-
-// static
-void* LLIMFloater::createPanelIMControl(void* userdata)
-{
- LLIMFloater *self = (LLIMFloater*)userdata;
- self->mControlPanel = new LLPanelIMControlPanel();
- self->mControlPanel->setXMLFilename("panel_im_control_panel.xml");
- return self->mControlPanel;
-}
-
-
-// static
-void* LLIMFloater::createPanelGroupControl(void* userdata)
-{
- LLIMFloater *self = (LLIMFloater*)userdata;
- self->mControlPanel = new LLPanelGroupControlPanel();
- self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
- return self->mControlPanel;
-}
-
-const U32 DOCK_ICON_HEIGHT = 6;
-
-//virtual
-void LLIMFloater::onFocusLost()
-{
- // spec says close if docked to bottom tray and user has clicked away
- // (hence we are no longer focused)
- if (isDocked())
- {
- LLIMFloater* floater = LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", mSessionID);
- if (floater)
- {
- floater->setVisible(false);
- }
- }
-}
-
-void LLIMFloater::onSlide()
-{
- LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
- im_control_panel->setVisible(!im_control_panel->getVisible());
-
- getChild<LLButton>("slide_left_btn")->setVisible(im_control_panel->getVisible());
- getChild<LLButton>("slide_right_btn")->setVisible(!im_control_panel->getVisible());
-}
-
-//static
-LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
-{
- //hide all
- LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
- for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
- iter != inst_list.end(); ++iter)
- {
- LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
- if (floater && floater->isDocked())
- {
- floater->setVisible(false);
- }
- }
-
- LLIMFloater* floater = LLFloaterReg::showTypedInstance<LLIMFloater>("impanel", session_id);
-
- floater->updateMessages();
- floater->mInputEditor->setFocus(TRUE);
-
- if (floater->getDockControl() == NULL)
- {
- LLView* chiclet =
- LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLView>(
- session_id);
- if (chiclet == NULL)
- {
- llerror("Dock chiclet for LLIMFloater doesn't exists", 0);
- }
- floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
- LLDockControl::TOP, floater->isDocked()));
- }
-
- return floater;
-}
-
-//static
-bool LLIMFloater::toggle(const LLUUID& session_id)
-{
- LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
- if (floater && floater->getVisible())
- {
- // clicking on chiclet to close floater just hides it to maintain existing
- // scroll/text entry state
- floater->setVisible(false);
- return false;
- }
- else
- {
- // ensure the list of messages is updated when floater is made visible
- show(session_id);
- // update number of unread notifications in the SysWell
- LLBottomTray::getInstance()->getSysWell()->updateUreadIMNotifications();
- return true;
- }
-}
-
-void LLIMFloater::updateMessages()
-{
- std::list<LLSD> messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1);
-
- if (messages.size())
- {
- LLUIColor divider_color = LLUIColorTable::instance().getColor("LtGray_50");
- LLUIColor chat_color = LLUIColorTable::instance().getColor("IMChatColor");
-
- std::ostringstream message;
- std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
- std::list<LLSD>::const_reverse_iterator iter_end = messages.rend();
- for (; iter != iter_end; ++iter)
- {
- LLSD msg = *iter;
-
- const bool prepend_newline = true;
- std::string from = msg["from"].asString();
- if (mLastFromName != from)
- {
- message << from << " ----- " << msg["time"].asString();
- mHistoryEditor->appendColoredText(message.str(), false,
- prepend_newline, divider_color);
- message.str("");
- mLastFromName = from;
- }
-
- message << msg["message"].asString();
- mHistoryEditor->appendColoredText(message.str(), false,
- prepend_newline, chat_color);
- message.str("");
-
- mLastMessageIndex = msg["index"].asInteger();
- }
-
- mHistoryEditor->setCursorAndScrollToEnd();
- }
-}
-
-// static
-void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
-{
- LLIMFloater* self= (LLIMFloater*) userdata;
- self->mHistoryEditor->setCursorAndScrollToEnd();
-}
-
-// static
-void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
-{
- LLIMFloater* self = (LLIMFloater*) userdata;
- self->setTyping(FALSE);
-}
-
-// static
-void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
-{
- LLIMFloater* self = (LLIMFloater*)userdata;
- std::string text = self->mInputEditor->getText();
- if (!text.empty())
- {
- self->setTyping(TRUE);
- }
- else
- {
- // Deleting all text counts as stopping typing.
- self->setTyping(FALSE);
- }
-}
-
-
-//just a stub for now
-void LLIMFloater::setTyping(BOOL typing)
-{
-}
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index 1d69f1567c..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,71 +352,9 @@ private:
// Timer to detect when user has stopped typing.
LLFrameTimer mLastKeystrokeTimer;
- void disableWhileSessionStarting();
-};
-
-
-// Individual IM window that appears at the bottom of the screen,
-// optionally "docked" to the bottom tray.
-class LLIMFloater : public LLDockableFloater
-{
-public:
- LLIMFloater(const LLUUID& session_id);
-
- virtual ~LLIMFloater();
-
- // LLView overrides
- /*virtual*/ BOOL postBuild();
-
- // Floater should close when user clicks away to other UI area,
- // hence causing focus loss.
- /*virtual*/ void onFocusLost();
-
- // Make IM conversion visible and update the message history
- static LLIMFloater* show(const LLUUID& session_id);
-
- // Toggle panel specified by session_id
- // Returns true iff panel became visible
- static bool toggle(const LLUUID& session_id);
-
- // get new messages from LLIMModel
- void updateMessages();
- static void onSendMsg( LLUICtrl*, void*);
- void sendMsg();
-
- // callback for LLIMModel on new messages
- // route to specific floater if it is visible
- static void newIMCallback(const LLSD& data);
-
- // called when docked floater's position has been set by chiclet
- void setPositioned(bool b) { mPositioned = b; };
+ boost::signals2::connection mFocusCallbackConnection;
-
-
-private:
-
- static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
- static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
- static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
- void setTyping(BOOL typing);
- void onSlide();
- static void* createPanelIMControl(void* userdata);
- static void* createPanelGroupControl(void* userdata);
-
- LLPanelChatControlPanel* mControlPanel;
- LLUUID mSessionID;
- S32 mLastMessageIndex;
- // username of last user who added text to this conversation, used to
- // suppress duplicate username divider bars
- std::string mLastFromName;
- EInstantMessage mDialog;
- LLUUID mOtherParticipantUUID;
- LLViewerTextEditor* mHistoryEditor;
- LLLineEditor* mInputEditor;
- bool mPositioned;
+ void disableWhileSessionStarting();
};
-
-
-
#endif // LL_IMPANEL_H
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a58cca1ba4..b5ac3526d2 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -53,6 +53,7 @@
#include "llfloaterchatterbox.h"
#include "llavataractions.h"
#include "llhttpnode.h"
+#include "llimfloater.h"
#include "llimpanel.h"
#include "llresizebar.h"
#include "lltabcontainer.h"
@@ -70,6 +71,7 @@
#include "llnotify.h"
#include "llviewerregion.h"
#include "lltrans.h"
+#include "llrecentpeople.h"
#include "llfirstuse.h"
#include "llagentui.h"
@@ -90,6 +92,11 @@ std::map<LLUUID, LLIMModel::LLIMSession*> LLIMModel::sSessionsMap;
void toast_callback(const LLSD& msg){
+ // do not show toast in busy mode
+ if (gAgent.getBusy())
+ {
+ return;
+ }
//we send notifications to reset counter also
if (msg["num_unread"].asInteger())
@@ -101,17 +108,90 @@ void toast_callback(const LLSD& msg){
args["FROM_ID"] = msg["from_id"];
args["SESSION_ID"] = msg["session_id"];
- //LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLFloaterChatterBox::onOpen, LLFloaterChatterBox::getInstance(), msg["session_id"].asUUID()));
- LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::toggle, msg["session_id"].asUUID()));
+ LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID()));
}
}
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()
{
@@ -147,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);
@@ -164,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;
@@ -196,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)
{
@@ -225,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)
{
@@ -254,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)
{
@@ -267,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)
@@ -310,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,
@@ -409,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);
}
@@ -627,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
@@ -644,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();
@@ -1098,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)
{
@@ -1163,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);
@@ -1267,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;
@@ -1306,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)
{
@@ -1329,24 +1498,24 @@ 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
// internal consistency. The internal pointer is not deleted? Did you mean
// a pointer to the corresponding LLIMSession? Session data is cleared now.
-void LLIMMgr::removeSession(const LLUUID& session_id)
+// Put a copy of UUID to avoid problem when passed reference becames invalid
+// if it has been come from the object removed in observer.
+void LLIMMgr::removeSession(LLUUID session_id)
{
+ if (mBeingRemovedSessionID == session_id)
+ {
+ return;
+ }
+
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if(floater)
{
@@ -1692,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;
}
@@ -1812,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
@@ -1919,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 4eb743b1ac..9a94d01bb2 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -34,11 +34,12 @@
#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"
#include "llmultifloater.h"
-#include "llrecentpeople.h"
class LLFloaterChatterBox;
class LLUUID;
@@ -51,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);
@@ -73,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);
@@ -159,7 +211,7 @@ public:
// This removes the panel referenced by the uuid, and then
// restores internal consistency. The internal pointer is not
// deleted.
- void removeSession(const LLUUID& session_id);
+ void removeSession(LLUUID session_id);
void inviteToSession(
const LLUUID& session_id,
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 40c5a243cc..e5cf8ccf66 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3084,8 +3084,15 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Landmark Separator"));
items.push_back(std::string("Teleport To Landmark"));
- hideContextEntries(menu, items, disabled_items);
+ // Disable "About Landmark" menu item for
+ // multiple landmarks selected. Only one landmark
+ // info panel can be shown at a time.
+ if ((flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Teleport To Landmark"));
+ }
+ hideContextEntries(menu, items, disabled_items);
}
// Convenience function for the two functions below.
diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp
index df9aa32d1b..0542199fc1 100644
--- a/indra/newview/lllandmarkactions.cpp
+++ b/indra/newview/lllandmarkactions.cpp
@@ -52,11 +52,16 @@
#include "llinventorymodel.h"
#include "llagentui.h"
-// Returns true if the given inventory item is a landmark pointing to the current parcel.
-// Used to filter inventory items.
-class LLIsAgentParcelLandmark : 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,8 +74,10 @@ public:
LLVector3d landmark_global_pos;
if (!landmark->getGlobalPos(landmark_global_pos))
return false;
-
- return LLViewerParcelMgr::getInstance()->inAgentParcel(landmark_global_pos);
+ //we have to round off each coordinates to compare positions properly
+ 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]);
}
};
@@ -139,24 +146,22 @@ LLInventoryModel::item_array_t LLLandmarkActions::fetchLandmarksByName(std::stri
bool LLLandmarkActions::landmarkAlreadyExists()
{
- // Determine whether there are landmarks pointing to the current parcel.
- LLInventoryModel::item_array_t items;
- collectParcelLandmark(items);
- return !items.empty();
+ // Determine whether there are landmarks pointing to the current global agent position.
+ return findLandmarkForAgentPos() != NULL;
}
-LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentParcel()
+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;
- LLIsAgentParcelLandmark is_current_parcel_landmark;
+ LLFetchlLandmarkByPos is_current_pos_landmark(pos);
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
- is_current_parcel_landmark);
+ is_current_pos_landmark);
if(items.empty())
{
@@ -166,6 +171,11 @@ LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentParcel()
return items[0];
}
+LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
+{
+ return findLandmarkForGlobalPos(gAgent.getPositionGlobal());
+}
+
bool LLLandmarkActions::canCreateLandmarkHere()
{
LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
@@ -287,13 +297,3 @@ bool LLLandmarkActions::getLandmarkGlobalPos(const LLUUID& landmarkInventoryItem
return landmark->getGlobalPos(posGlobal);
}
-
-void LLLandmarkActions::collectParcelLandmark(LLInventoryModel::item_array_t& items){
- LLInventoryModel::cat_array_t cats;
- LLIsAgentParcelLandmark is_current_parcel_landmark;
- gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- is_current_parcel_landmark);
-}
diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h
index c74072c0f4..ab8cc4d6a5 100644
--- a/indra/newview/lllandmarkactions.h
+++ b/indra/newview/lllandmarkactions.h
@@ -53,12 +53,21 @@ public:
static bool landmarkAlreadyExists();
/**
- * @brief Searches landmark for parcel agent is currently in.
- * @return Returns landmark for agent parcel or NULL.
+ * @brief Searches landmark for global position.
+ * @return Returns landmark or NULL.
*
* *TODO: dzaporozhan: There can be many landmarks for single parcel.
*/
- static LLViewerInventoryItem* findLandmarkForAgentParcel();
+ static LLViewerInventoryItem* findLandmarkForGlobalPos(const LLVector3d &pos);
+
+ /**
+ * @brief Searches landmark for agent global position.
+ * @return Returns landmark or NULL.
+ *
+ * *TODO: dzaporozhan: There can be many landmarks for single parcel.
+ */
+ static LLViewerInventoryItem* findLandmarkForAgentPos();
+
/**
* @brief Checks whether agent has rights to create landmark for current parcel.
@@ -77,14 +86,6 @@ public:
const std::string& name,
const std::string& desc,
const LLUUID& folder_id);
-
- /**
- * @brief Trying to find in inventory a landmark of the current parcel.
- * Normally items should contain only one item,
- * because we can create the only landmark per parcel according to Navigation spec.
- */
- static void collectParcelLandmark(LLInventoryModel::item_array_t& items);
-
/**
* @brief Creates SLURL for given global position.
*/
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 1d9220cf3d..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);
@@ -419,8 +418,7 @@ void LLLocationInputCtrl::onInfoButtonClicked()
void LLLocationInputCtrl::onAddLandmarkButtonClicked()
{
- LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentParcel();
-
+ LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
// Landmark exists, open it for preview and edit
if(landmark && landmark->getUUID().notNull())
{
@@ -658,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));
@@ -677,15 +676,16 @@ void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata)
}
else if (item == std::string("landmark"))
{
- LLInventoryModel::item_array_t items;
- LLLandmarkActions::collectParcelLandmark(items);
+ LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
- if(items.empty())
+ if(!landmark)
{
LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark"));
- }else{
+ }
+ else
+ {
LLSideTray::getInstance()->showPanel("panel_places",
- LLSD().insert("type", "landmark").insert("id",items.get(0)->getUUID()));
+ LLSD().insert("type", "landmark").insert("id",landmark->getUUID()));
}
}
else if (item == std::string("cut"))
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/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 11c8b03f7f..d8f00ec370 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -71,7 +71,7 @@ const std::string BOTTOM_TRAY_BUTTON_NAME = "movement_btn";
// protected
LLFloaterMove::LLFloaterMove(const LLSD& key)
-: LLFloater(key),
+: LLDockableFloater(NULL, false, key),
mForwardButton(NULL),
mBackwardButton(NULL),
mTurnLeftButton(NULL),
@@ -79,7 +79,8 @@ LLFloaterMove::LLFloaterMove(const LLSD& key)
mMoveUpButton(NULL),
mMoveDownButton(NULL),
mStopFlyingButton(NULL),
- mModeActionsPanel(NULL)
+ mModeActionsPanel(NULL),
+ mCurrentMode(MM_WALK)
{
}
@@ -88,6 +89,7 @@ BOOL LLFloaterMove::postBuild()
{
setIsChrome(TRUE);
+ LLDockableFloater::postBuild();
mForwardButton = getChild<LLJoystickAgentTurn>("forward btn");
mForwardButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
@@ -134,8 +136,6 @@ BOOL LLFloaterMove::postBuild()
initModeTooltips();
- updatePosition();
-
initModeButtonMap();
initMovementMode();
@@ -145,6 +145,18 @@ BOOL LLFloaterMove::postBuild()
return TRUE;
}
+// virtual
+void LLFloaterMove::setEnabled(BOOL enabled)
+{
+ //we need to enable/disable only buttons, EXT-1061.
+
+ // is called before postBuild() - use findChild here.
+ LLPanel *panel_actions = findChild<LLPanel>("panel_actions");
+ if (panel_actions) panel_actions->setEnabled(enabled);
+
+ showModeButtons(enabled);
+}
+
// static
F32 LLFloaterMove::getYawRate( F32 time )
{
@@ -266,6 +278,7 @@ void LLFloaterMove::onStopFlyingButtonClick()
void LLFloaterMove::setMovementMode(const EMovementMode mode)
{
+ mCurrentMode = mode;
gAgent.setFlying(MM_FLY == mode);
switch (mode)
@@ -401,26 +414,49 @@ void LLFloaterMove::sUpdateFlyingStatus()
void LLFloaterMove::showModeButtons(BOOL bShow)
{
- if (mModeActionsPanel->getVisible() == bShow)
+ // is called from setEnabled so can be called before postBuild(), check mModeActionsPanel agains to NULL
+ if (NULL == mModeActionsPanel || mModeActionsPanel->getVisible() == bShow)
return;
mModeActionsPanel->setVisible(bShow);
+ if (isDocked())
+ {
+ return;
+ }
+
+ updateHeight(bShow);
+}
+
+void LLFloaterMove::updateHeight(bool show_mode_buttons)
+{
+ static bool size_changed = false;
+ static S32 origin_height = getRect().getHeight();
LLRect rect = getRect();
- static S32 height = mModeActionsPanel->getRect().getHeight();
+ static S32 mode_panel_height = mModeActionsPanel->getRect().getHeight();
+
S32 newHeight = getRect().getHeight();
- if (!bShow)
+
+ if (!show_mode_buttons && origin_height == newHeight)
{
- newHeight -= height;
+ newHeight -= mode_panel_height;
+ size_changed = true;
}
- else
+ else if (show_mode_buttons && origin_height > newHeight)
{
- newHeight += height;
+ newHeight += mode_panel_height;
+ size_changed = true;
}
+
+ if (!size_changed)
+ return;
+
rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), newHeight);
reshape(rect.getWidth(), rect.getHeight());
setRect(rect);
+ size_changed = false;
}
+
//static
void LLFloaterMove::enableInstance(BOOL bEnable)
{
@@ -428,17 +464,42 @@ void LLFloaterMove::enableInstance(BOOL bEnable)
if (instance)
{
instance->setEnabled(bEnable);
- instance->showModeButtons(bEnable);
}
}
void LLFloaterMove::onOpen(const LLSD& key)
{
- updatePosition();
+ LLButton *anchor_panel = LLBottomTray::getInstance()->getChild<LLButton>("movement_btn");
+
+ if (gAgent.getFlying())
+ {
+ setFlyingMode(TRUE);
+ showModeButtons(FALSE);
+ }
+
+ if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting())
+ {
+ setSittingMode(TRUE);
+ showModeButtons(FALSE);
+ }
+
+ setDockControl(new LLDockControl(
+ anchor_panel, this,
+ getDockTongue(), LLDockControl::TOP));
+
+ showQuickTips(mCurrentMode);
sUpdateFlyingStatus();
}
+//virtual
+void LLFloaterMove::setDocked(bool docked, bool pop_on_undock/* = true*/)
+{
+ LLDockableFloater::setDocked(docked, pop_on_undock);
+ bool show_mode_buttons = isDocked() || !gAgent.getFlying();
+ updateHeight(show_mode_buttons);
+}
+
void LLFloaterMove::showQuickTips(const EMovementMode mode)
{
LLFirstTimeTipsManager::EFirstTimeTipType tipType = LLFirstTimeTipsManager::FTT_MOVE_WALK;
@@ -543,6 +604,7 @@ void LLPanelStandStopFlying::setVisible(BOOL visible)
if (visible)
{
updatePosition();
+ getParent()->sendChildToFront(this);
}
LLPanel::setVisible(visible);
@@ -600,6 +662,15 @@ void LLPanelStandStopFlying::updatePosition()
S32 y = tray->getRect().getHeight();
+ LLFloater *move_floater = LLFloaterReg::findInstance("moveview");
+ if (move_floater)
+ {
+ if (move_floater->isDocked())
+ {
+ y = move_floater->getRect().mBottom + getRect().getHeight();
+ }
+ }
+
setOrigin(x, y);
}
diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h
index 6e6af9b693..584c7c494c 100644
--- a/indra/newview/llmoveview.h
+++ b/indra/newview/llmoveview.h
@@ -34,7 +34,7 @@
#define LL_LLMOVEVIEW_H
// Library includes
-#include "llfloater.h"
+#include "lldockablefloater.h"
class LLButton;
class LLJoystickAgentTurn;
@@ -44,7 +44,7 @@ class LLJoystickAgentSlide;
// Classes
//
class LLFloaterMove
-: public LLFloater
+: public LLDockableFloater
{
friend class LLFloaterReg;
@@ -54,6 +54,7 @@ private:
public:
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void setEnabled(BOOL enabled);
static F32 getYawRate(F32 time);
static void setFlyingMode(BOOL fly);
void setFlyingModeImpl(BOOL fly);
@@ -62,10 +63,7 @@ public:
static void setSittingMode(BOOL bSitting);
static void enableInstance(BOOL bEnable);
/*virtual*/ void onOpen(const LLSD& key);
-
- // *HACK: due to hard enough to have this control aligned with "Move" button while resizing
- // let update its position in each frame
- /*virtual*/ void draw(){updatePosition(); LLFloater::draw();}
+ /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
static void sUpdateFlyingStatus();
@@ -98,6 +96,7 @@ private:
void updateButtonsWithMovementMode(const EMovementMode newMode);
void updatePosition();
void showModeButtons(BOOL bShow);
+ void updateHeight(bool show_mode_buttons);
public:
@@ -117,6 +116,7 @@ private:
typedef std::map<EMovementMode, LLButton*> mode_control_button_map_t;
mode_control_button_map_t mModeControlButtonMap;
+ EMovementMode mCurrentMode;
};
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 6150d5da37..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()->getChannelByID(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 e348189ea9..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 );
@@ -201,6 +201,35 @@ BOOL LLNearbyChatBar::postBuild()
mChatBox->setMaxTextLength(1023);
mChatBox->setEnableLineHistory(TRUE);
+ // TODO: Initialization of the output monitor's params should be done via xml
+ const S32 MONITOR_RIGHT_PAD = 2;
+
+ LLRect monitor_rect = LLRect(0, 18, 18, 0);
+ LLRect chatbox_rect = mChatBox->getRect();
+
+ S32 monitor_height = monitor_rect.getHeight();
+ monitor_rect.mLeft = chatbox_rect.getWidth() - monitor_rect.getWidth() - MONITOR_RIGHT_PAD;
+ monitor_rect.mRight = chatbox_rect.getWidth() - MONITOR_RIGHT_PAD;
+ monitor_rect.mBottom = (chatbox_rect.getHeight() / 2) - (monitor_height / 2);
+ monitor_rect.mTop = monitor_rect.mBottom + monitor_height;
+
+ LLOutputMonitorCtrl::Params monitor_params = LLOutputMonitorCtrl::Params();
+ monitor_params.name = "output_monitor";
+ monitor_params.draw_border(false);
+ monitor_params.rect(monitor_rect);
+ monitor_params.auto_update(true);
+ monitor_params.speaker_id(gAgentID);
+
+ LLView::Follows follows = LLView::Follows();
+ follows.flags = FOLLOWS_RIGHT;
+ monitor_params.follows = follows;
+ mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params);
+ mChatBox->addChild(mOutputMonitor);
+
+ // never show "muted" because you can't mute yourself
+ mOutputMonitor->setIsMuted(false);
+ mOutputMonitor->setVisible(FALSE);
+
mTalkBtn = getChild<LLTalkButton>("talk");
// Speak button should be initially disabled because
@@ -593,6 +622,7 @@ LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channe
void LLNearbyChatBar::setPTTState(bool state)
{
mTalkBtn->setSpeakBtnToggleState(state);
+ mOutputMonitor->setVisible(state);
}
void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index f310740f42..1b71ad69f2 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -39,6 +39,7 @@
#include "llchat.h"
#include "llchiclet.h"
#include "llvoiceclient.h"
+#include "lloutputmonitorctrl.h"
class LLGestureComboBox
: public LLComboBox
@@ -114,6 +115,7 @@ protected:
LLLineEditor* mChatBox;
LLTalkButton* mTalkBtn;
+ LLOutputMonitorCtrl* mOutputMonitor;
};
#endif
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index a1912655a3..eb42e83994 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -41,31 +41,230 @@
#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;
- LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
- /////////////////////////////////////////////////////
- LLChannelManager::Params p; //TODO: check and correct
- p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
- p.channel_right_bound = nearby_chat->getRect().mRight;
- p.channel_width = nearby_chat->getRect().mRight - 16; //HACK: 16 - ?
- /////////////////////////////////////////////////////
-
// Getting a Channel for our notifications
- mChannel = LLChannelManager::getInstance()->createChannel(p);
- mChannel->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_TOP);
+ 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;
+ mChannel->init(channel_right_bound - channel_width, channel_right_bound);
+}
+
void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
{
if(chat_msg.mMuted == TRUE)
@@ -75,55 +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.id = id;
- p.panel = item;
- p.on_toast_destroy = boost::bind(&LLNearbyChatHandler::onToastDestroy, this, _1);
- p.on_mouse_enter = boost::bind(&LLNearbyChatHandler::removeNearbyToastsAndShowChat, this);
- 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;
-void LLNearbyChatHandler::onToastDestroy(LLToast* toast)
-{
- if(toast)
- toast->closeFloater();
+ channel->addNotification(notification);
+ }
+
}
-void LLNearbyChatHandler::onChicletClick(void)
-{
-}
-void LLNearbyChatHandler::onChicletClose(void)
+void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
{
}
-void LLNearbyChatHandler::removeNearbyToastsAndShowChat()
-{
- /*
- if(mChannel)
- mChannel->removeToastsFromChannel();
-
- LLFloaterReg::showTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
- */
-}
-}
diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llnearbychathandler.h
index 8fcd03689d..fb2abac6a4 100644
--- a/indra/newview/llnearbychathandler.h
+++ b/indra/newview/llnearbychathandler.h
@@ -46,12 +46,10 @@ public:
virtual void processChat(const LLChat& chat_msg);
- virtual void onToastDestroy(LLToast* toast);
- virtual void onChicletClick(void);
- virtual void onChicletClose(void);
protected:
- void removeNearbyToastsAndShowChat();
+ virtual void onDeleteToast(LLToast* toast);
+ virtual void initChannel();
};
}
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index bd6c6b2308..1be03cef0b 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -35,8 +35,8 @@
#include "llnotificationhandler.h"
#include "lltoastnotifypanel.h"
-#include "llbottomtray.h"
#include "llviewercontrol.h"
+#include "llviewerwindow.h"
#include "lltoastalertpanel.h"
@@ -47,18 +47,15 @@ LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsMo
{
mType = type;
- LLBottomTray* tray = LLBottomTray::getInstance();
LLChannelManager::Params p;
p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID"));
- p.channel_right_bound = tray->getRect().getWidth() / 2;
- p.channel_width = 0;
p.display_toasts_always = true;
- p.align = NA_CENTRE;
+ p.toast_align = NA_CENTRE;
+ p.channel_align = CA_CENTRE;
// Getting a Channel for our notifications
- mChannel = LLChannelManager::getInstance()->createChannel(p);
- mChannel->setFollows(FOLLOWS_BOTTOM | FOLLOWS_TOP);
- mChannel->setShowToasts(true);
+ mChannel = LLChannelManager::getInstance()->getChannel(p);
+ mChannel->setCanStoreToasts(false);
}
//--------------------------------------------------------------------------
@@ -67,51 +64,68 @@ LLAlertHandler::~LLAlertHandler()
}
//--------------------------------------------------------------------------
-void LLAlertHandler::processNotification(const LLSD& notify)
+void LLAlertHandler::initChannel()
{
+ S32 channel_right_bound = gViewerWindow->getWorldViewRect().getWidth() / 2;
+ mChannel->init(channel_right_bound, channel_right_bound);
+}
+
+//--------------------------------------------------------------------------
+bool LLAlertHandler::processNotification(const LLSD& notify)
+{
+ if(!mChannel)
+ {
+ return false;
+ }
+
LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
+ if(!notification)
+ return false;
+
+ // arrange a channel on a screen
+ if(!mChannel->getVisible())
+ {
+ initChannel();
+ }
+
if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load")
{
LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
LLToast::Params p;
- p.id = notification->getID();
+ p.notif_id = notification->getID();
p.notification = notification;
p.panel = dynamic_cast<LLToastPanel*>(alert_dialog);
p.enable_hide_btn = false;
p.can_fade = false;
p.is_modal = mIsModal;
- p.on_toast_destroy = boost::bind(&LLAlertHandler::onToastDestroy, this, _1);
- mChannel->addToast(p);
+ p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
+
+ 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;
}
//--------------------------------------------------------------------------
-void LLAlertHandler::onToastDestroy(LLToast* toast)
-{
- toast->closeFloater();
-}
-
-//--------------------------------------------------------------------------
-void LLAlertHandler::onChicletClick(void)
-{
-}
-
-//--------------------------------------------------------------------------
-void LLAlertHandler::onChicletClose(void)
+void LLAlertHandler::onDeleteToast(LLToast* toast)
{
}
//--------------------------------------------------------------------------
-
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index 31753efec9..ffa92b543c 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -34,11 +34,9 @@
#include "llnotificationhandler.h"
#include "lltoastgroupnotifypanel.h"
-#include "llbottomtray.h"
#include "llgroupactions.h"
#include "llviewercontrol.h"
-#include "llfloaterreg.h"
-#include "llsyswellwindow.h"
+#include "llviewerwindow.h"
using namespace LLNotificationsUI;
@@ -47,16 +45,8 @@ LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id)
{
mType = type;
- // getting a Chiclet and creating params for a channel
- LLBottomTray* tray = LLBottomTray::getInstance();
- mChiclet = tray->getSysWell();
- LLChannelManager::Params p;
- p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID"));
- p.channel_right_bound = tray->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
- p.channel_width = gSavedSettings.getS32("NotifyBoxWidth");
-
// Getting a Channel for our notifications
- mChannel = LLChannelManager::getInstance()->createChannel(p);
+ mChannel = LLChannelManager::getInstance()->createNotificationChannel();
}
//--------------------------------------------------------------------------
@@ -65,52 +55,66 @@ LLGroupHandler::~LLGroupHandler()
}
//--------------------------------------------------------------------------
-void LLGroupHandler::processNotification(const LLSD& notify)
+void LLGroupHandler::initChannel()
{
+ S32 channel_right_bound = gViewerWindow->getWorldViewRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+ mChannel->init(channel_right_bound - channel_width, channel_right_bound);
+}
+
+//--------------------------------------------------------------------------
+bool LLGroupHandler::processNotification(const LLSD& notify)
+{
+ if(!mChannel)
+ {
+ return false;
+ }
+
LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
+
+ if(!notification)
+ return false;
+
+ // arrange a channel on a screen
+ if(!mChannel->getVisible())
+ {
+ initChannel();
+ }
+
if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
{
LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
LLToast::Params p;
- p.id = notification->getID();
+ p.notif_id = notification->getID();
p.notification = notification;
p.panel = notify_box;
- p.on_toast_destroy = boost::bind(&LLGroupHandler::onToastDestroy, this, _1);
- mChannel->addToast(p);
- static_cast<LLNotificationChiclet*>(mChiclet)->incUreadSystemNotifications();
-
- LLGroupActions::refresh_notices();
+ p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
+
+ // send a signal to the counter manager
+ mNewNotificationSignal();
+
+ LLGroupActions::refresh_notices();
}
else if (notify["sigtype"].asString() == "delete")
{
mChannel->killToastByNotificationID(notification->getID());
}
+ return true;
}
//--------------------------------------------------------------------------
-void LLGroupHandler::onToastDestroy(LLToast* toast)
+void LLGroupHandler::onDeleteToast(LLToast* toast)
{
- static_cast<LLNotificationChiclet*>(mChiclet)->decUreadSystemNotifications();
-
- LLToastPanel* panel = dynamic_cast<LLToastPanel*>(toast->getPanel());
- LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window")->removeItemByID(panel->getID());
-
- // turning hovering off mannualy because onMouseLeave won't happen if a toast was closed using a keyboard
- if(toast->hasFocus())
- mChannel->setHovering(false);
-
- toast->closeFloater();
-}
+ // send a signal to the counter manager
+ mDelNotificationSignal();
-//--------------------------------------------------------------------------
-void LLGroupHandler::onChicletClick(void)
-{
-}
-
-//--------------------------------------------------------------------------
-void LLGroupHandler::onChicletClose(void)
-{
+ // send a signal to a listener to let him perform some action
+ // in this case listener is a SysWellWindow and it will remove a corresponding item from its list
+ mNotificationIDSignal(toast->getNotificationID());
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 6982ab7096..cd4e640ec4 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -65,33 +65,54 @@ typedef enum e_notification_type
// LLEventHandler is a base class that specifies a common interface for all
// notification handlers. It states, that every handler must react on the follofing
// events:
-// - destroying of a toast;
-// - clicking on a correspondet chiclet;
-// - closing of a correspondent chiclet.
+// - deleting of a toast;
+// - initialization of a corresponding channel;
// Also every handler must have the following attributes:
// - type of the notification that this handler is responsible to;
-// - pointer to a correspondent chiclet;
// - pointer to a correspondent screen channel, in which all toasts of the handled notification's
// type should be displayed
+// This class also provides the following signald:
+// - increment counter signal
+// - decrement counter signal
+// - update counter signal
+// - signal, that emits ID of the notification that is being processed
//
class LLEventHandler
{
public:
virtual ~LLEventHandler() {};
- virtual void onToastDestroy(LLToast* toast)=0;
- virtual void onChicletClick(void)=0;
- virtual void onChicletClose(void)=0;
+ // callbacks for counters
+ typedef boost::function<void (void)> notification_callback_t;
+ typedef boost::signals2::signal<void (void)> notification_signal_t;
+ notification_signal_t mNewNotificationSignal;
+ notification_signal_t mDelNotificationSignal;
+ boost::signals2::connection setNewNotificationCallback(notification_callback_t cb) { return mNewNotificationSignal.connect(cb); }
+ boost::signals2::connection setDelNotification(notification_callback_t cb) { return mDelNotificationSignal.connect(cb); }
+ // callback for notification/toast
+ typedef boost::function<void (const LLUUID id)> notification_id_callback_t;
+ typedef boost::signals2::signal<void (const LLUUID id)> notification_id_signal_t;
+ notification_id_signal_t mNotificationIDSignal;
+ boost::signals2::connection setNotificationIDCallback(notification_id_callback_t cb) { return mNotificationIDSignal.connect(cb); }
+
+protected:
+ virtual void onDeleteToast(LLToast* toast)=0;
+
+ // arrange handler's channel on a screen
+ // is necessary to unbind a moment of creation of a channel and a moment of positioning of it
+ // it is useful when positioning depends on positions of other controls, that could not be created
+ // at the moment, when a handlers creates a channel.
+ virtual void initChannel()=0;
+
+ LLScreenChannelBase* mChannel;
+ e_notification_type mType;
- LLScreenChannel* mChannel;
- LLChiclet* mChiclet;
- e_notification_type mType;
};
// LLSysHandler and LLChatHandler are more specific base classes
// that divide all notification handlers on to groups:
-// - handlers for different system notifications (script dialogs, tips, group notices and alerts);
-// - handlers for different messaging notifications (nearby chat, IM chat, group chat etc.)
+// - handlers for different system notifications (script dialogs, tips, group notices, alerts and IMs);
+// - handlers for different messaging notifications (nearby chat)
/**
* Handler for system notifications.
*/
@@ -100,7 +121,7 @@ class LLSysHandler : public LLEventHandler
public:
virtual ~LLSysHandler() {};
- virtual void processNotification(const LLSD& notify)=0;
+ virtual bool processNotification(const LLSD& notify)=0;
};
/**
@@ -116,43 +137,59 @@ public:
/**
* Handler for IM notifications.
- * It manages life time of tip and script notices.
+ * It manages life time of IMs, group messages.
*/
class LLIMHandler : public LLSysHandler
{
public:
- LLIMHandler();
+ LLIMHandler(e_notification_type type, const LLSD& id);
virtual ~LLIMHandler();
// base interface functions
- virtual void processNotification(const LLSD& notify);
- virtual void onToastDestroy(LLToast* toast);
- virtual void onChicletClick(void);
- virtual void onChicletClose(void);
+ virtual bool processNotification(const LLSD& notify);
protected:
+ virtual void onDeleteToast(LLToast* toast);
+ virtual void initChannel();
};
/**
* Handler for system informational notices.
- * It manages life time of tip and script notices.
+ * It manages life time of tip notices.
*/
-class LLInfoHandler : public LLSysHandler
+class LLTipHandler : public LLSysHandler
{
public:
- LLInfoHandler(e_notification_type type, const LLSD& id);
- virtual ~LLInfoHandler();
+ LLTipHandler(e_notification_type type, const LLSD& id);
+ virtual ~LLTipHandler();
// base interface functions
- virtual void processNotification(const LLSD& notify);
- virtual void onToastDestroy(LLToast* toast);
- virtual void onChicletClick(void);
- virtual void onChicletClose(void);
+ virtual bool processNotification(const LLSD& notify);
- // own handlers
- void onStoreToast(LLPanel* info_panel, LLUUID id);
- void onRejectToast(LLToast::Params p);
protected:
+ virtual void onDeleteToast(LLToast* toast);
+ virtual void initChannel();
+};
+
+/**
+ * Handler for system informational notices.
+ * It manages life time of script notices.
+ */
+class LLScriptHandler : public LLSysHandler
+{
+public:
+ LLScriptHandler(e_notification_type type, const LLSD& id);
+ virtual ~LLScriptHandler();
+
+ // base interface functions
+ virtual bool processNotification(const LLSD& notify);
+
+protected:
+ virtual void onDeleteToast(LLToast* toast);
+ virtual void initChannel();
+
+ // own handlers
+ void onRejectToast(LLUUID& id);
};
@@ -164,14 +201,13 @@ class LLGroupHandler : public LLSysHandler
public:
LLGroupHandler(e_notification_type type, const LLSD& id);
virtual ~LLGroupHandler();
-
-
- virtual void processNotification(const LLSD& notify);
- virtual void onToastDestroy(LLToast* toast);
- virtual void onChicletClick(void);
- virtual void onChicletClose(void);
+
+ // base interface functions
+ virtual bool processNotification(const LLSD& notify);
protected:
+ virtual void onDeleteToast(LLToast* toast);
+ virtual void initChannel();
};
/**
@@ -185,12 +221,13 @@ public:
void setAlertMode(bool is_modal) { mIsModal = is_modal; }
- virtual void processNotification(const LLSD& notify);
- virtual void onToastDestroy(LLToast* toast);
- virtual void onChicletClick(void);
- virtual void onChicletClose(void);
+ // base interface functions
+ virtual bool processNotification(const LLSD& notify);
protected:
+ virtual void onDeleteToast(LLToast* toast);
+ virtual void initChannel();
+
bool mIsModal;
};
diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp
index 31266fdecf..81a6b32917 100644
--- a/indra/newview/llnotificationmanager.cpp
+++ b/indra/newview/llnotificationmanager.cpp
@@ -71,12 +71,13 @@ void LLNotificationManager::init()
LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
LLNotifications::instance().getChannel("IM Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLInfoHandler(NT_NOTIFY, LLSD()));
- mNotifyHandlers["notifytip"] = mNotifyHandlers["notify"];
+ mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD()));
+ mNotifyHandlers["notifytip"] = boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD()));
mNotifyHandlers["groupnotify"] = boost::shared_ptr<LLEventHandler>(new LLGroupHandler(NT_GROUPNOTIFY, LLSD()));
mNotifyHandlers["alert"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
- mNotifyHandlers["alertmodal"] = mNotifyHandlers["alert"];
- mNotifyHandlers["notifytoast"] = boost::shared_ptr<LLEventHandler>(new LLIMHandler());
+ mNotifyHandlers["alertmodal"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
+ static_cast<LLAlertHandler*>(mNotifyHandlers["alertmodal"].get())->setAlertMode(true);
+ mNotifyHandlers["notifytoast"] = boost::shared_ptr<LLEventHandler>(new LLIMHandler(NT_IMCHAT, LLSD()));
mNotifyHandlers["nearbychat"] = boost::shared_ptr<LLEventHandler>(new LLNearbyChatHandler(NT_NEARBYCHAT, LLSD()));
}
@@ -92,17 +93,12 @@ bool LLNotificationManager::onNotification(const LLSD& notify)
return false;
std::string notification_type = notification->getType();
- handle = dynamic_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get());
+ handle = static_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get());
if(!handle)
return false;
- if( notification_type == "alertmodal" )
- dynamic_cast<LLAlertHandler*>(handle)->setAlertMode(true);
-
- handle->processNotification(notify);
-
- return true;
+ return handle->processNotification(notify);
}
//--------------------------------------------------------------------------
@@ -124,7 +120,15 @@ void LLNotificationManager::onChat(const LLChat& msg,ENotificationType type)
}
//--------------------------------------------------------------------------
+LLEventHandler* LLNotificationManager::getHandlerForNotification(std::string notification_type)
+{
+ std::map<std::string, boost::shared_ptr<LLEventHandler> >::iterator it = mNotifyHandlers.find(notification_type);
+ if(it != mNotifyHandlers.end())
+ return (*it).second.get();
+ return NULL;
+}
+//--------------------------------------------------------------------------
diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h
index 838a00ee11..072fc6f24c 100644
--- a/indra/newview/llnotificationmanager.h
+++ b/indra/newview/llnotificationmanager.h
@@ -50,7 +50,7 @@ class LLToast;
/**
* Responsible for registering notification handlers.
*/
-class LLNotificationManager : public LLUICtrl, public LLSingleton<LLNotificationManager>
+class LLNotificationManager : public LLSingleton<LLNotificationManager>
{
typedef std::pair<std::string, LLEventHandler*> eventhandlers;
public:
@@ -68,6 +68,10 @@ public:
// this method reacts on chat notifications and calls an appropriate handler
void onChat(const LLChat& msg,ENotificationType type);
+ // get a handler for a certain type of notification
+ LLEventHandler* getHandlerForNotification(std::string notification_type);
+
+
private:
//TODO (*)
std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers;
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
new file mode 100644
index 0000000000..070af432d6
--- /dev/null
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -0,0 +1,142 @@
+/**
+ * @file llnotificationscripthandler.cpp
+ * @brief Notification Handler Class for Simple Notifications and Notification Tips
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-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" // must be first include
+
+#include "llnotificationhandler.h"
+#include "lltoastnotifypanel.h"
+#include "llviewercontrol.h"
+#include "llviewerwindow.h"
+
+using namespace LLNotificationsUI;
+
+//--------------------------------------------------------------------------
+LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
+{
+ mType = type;
+
+ // Getting a Channel for our notifications
+ mChannel = LLChannelManager::getInstance()->createNotificationChannel();
+ mChannel->setControlHovering(true);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+
+}
+
+//--------------------------------------------------------------------------
+LLScriptHandler::~LLScriptHandler()
+{
+}
+
+//--------------------------------------------------------------------------
+void LLScriptHandler::initChannel()
+{
+ S32 channel_right_bound = gViewerWindow->getWorldViewRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+ mChannel->init(channel_right_bound - channel_width, channel_right_bound);
+}
+
+//--------------------------------------------------------------------------
+bool LLScriptHandler::processNotification(const LLSD& notify)
+{
+ if(!mChannel)
+ {
+ return false;
+ }
+
+ LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
+
+ if(!notification)
+ return false;
+
+ // arrange a channel on a screen
+ if(!mChannel->getVisible())
+ {
+ initChannel();
+ }
+
+ if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
+ {
+ LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
+
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.notification = notification;
+ p.panel = notify_box;
+ p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
+
+ // send a signal to the counter manager
+ mNewNotificationSignal();
+
+ }
+ else if (notify["sigtype"].asString() == "delete")
+ {
+ mChannel->killToastByNotificationID(notification->getID());
+ }
+ return true;
+}
+
+//--------------------------------------------------------------------------
+
+void LLScriptHandler::onDeleteToast(LLToast* toast)
+{
+ // send a signal to the counter manager
+ mDelNotificationSignal();
+
+ // send a signal to a listener to let him perform some action
+ // in this case listener is a SysWellWindow and it will remove a corresponding item from its list
+ mNotificationIDSignal(toast->getNotificationID());
+}
+
+//--------------------------------------------------------------------------
+void LLScriptHandler::onRejectToast(LLUUID& id)
+{
+ LLNotificationPtr notification = LLNotifications::instance().find(id);
+
+ if(notification)
+ {
+ LLNotifications::instance().cancel(notification);
+ }
+}
+
+//--------------------------------------------------------------------------
+
+
+
+
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
new file mode 100644
index 0000000000..5186a93569
--- /dev/null
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -0,0 +1,114 @@
+/**
+ * @file llnotificationtiphandler.cpp
+ * @brief Notification Handler Class for Notification Tips
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-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" // must be first include
+
+#include "llnotificationhandler.h"
+#include "lltoastnotifypanel.h"
+#include "llviewercontrol.h"
+#include "llviewerwindow.h"
+
+using namespace LLNotificationsUI;
+
+
+//--------------------------------------------------------------------------
+LLTipHandler::LLTipHandler(e_notification_type type, const LLSD& id)
+{
+ mType = type;
+
+ // Getting a Channel for our notifications
+ mChannel = LLChannelManager::getInstance()->createNotificationChannel();
+}
+
+//--------------------------------------------------------------------------
+LLTipHandler::~LLTipHandler()
+{
+}
+
+//--------------------------------------------------------------------------
+void LLTipHandler::initChannel()
+{
+ S32 channel_right_bound = gViewerWindow->getWorldViewRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+ mChannel->init(channel_right_bound - channel_width, channel_right_bound);
+}
+
+//--------------------------------------------------------------------------
+bool LLTipHandler::processNotification(const LLSD& notify)
+{
+ if(!mChannel)
+ {
+ return false;
+ }
+
+ LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
+
+ if(!notification)
+ return false;
+
+ // arrange a channel on a screen
+ if(!mChannel->getVisible())
+ {
+ initChannel();
+ }
+
+ if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
+ {
+ LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
+
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.notification = notification;
+ p.panel = notify_box;
+ p.is_tip = true;
+ p.can_be_stored = false;
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
+ }
+ else if (notify["sigtype"].asString() == "delete")
+ {
+ mChannel->killToastByNotificationID(notification->getID());
+ }
+ return true;
+}
+
+//--------------------------------------------------------------------------
+void LLTipHandler::onDeleteToast(LLToast* toast)
+{
+}
+
+//--------------------------------------------------------------------------
+
+
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 49b48f5a8e..d9cdf2e04f 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -132,7 +132,7 @@ void LLOutputMonitorCtrl::draw()
if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull())
{
setPower(gVoiceClient->getCurrentPower(mSpeakerId));
- setIsTalking(gVoiceClient->getUserPTTState());
+ setIsTalking(gVoiceClient->getIsSpeaking(mSpeakerId));
}
LLPointer<LLUIImage> icon;
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index b7f2f67a9a..7ccff73080 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -311,8 +311,9 @@ void LLPanelProfileTab::onOpen(const LLSD& key)
void LLPanelProfileTab::scrollToTop()
{
- LLScrollContainer* scrollContainer = getChild<LLScrollContainer>("profile_scroll");
- scrollContainer->goToTop();
+ LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
+ if (scrollContainer)
+ 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 d1ce6b14ed..2b584910a3 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -44,6 +44,9 @@
#include "llfloaterreg.h"
#include "llfloater.h"
+#include "llagent.h"
+#include "llstatusbar.h" // can_afford_transaction()
+
#include "llsidetraypanelcontainer.h"
#include "llpanelgroupnotices.h"
@@ -162,15 +165,25 @@ BOOL LLPanelGroup::postBuild()
button->setEnabled(false);
+ button = getChild<LLButton>("btn_join");
+ button->setVisible(false);
+ button->setEnabled(true);
+
+ button = getChild<LLButton>("btn_cancel");
+ button->setVisible(false); button->setEnabled(true);
+
button = getChild<LLButton>("btn_refresh");
button->setClickedCallback(onBtnRefresh, this);
button->setVisible(mAllowEdit);
getChild<LLButton>("btn_create")->setVisible(false);
- childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL);
childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL);
+ childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL);
+ childSetCommitCallback("btn_join",boost::bind(&LLPanelGroup::onBtnJoin,this),NULL);
+ childSetCommitCallback("btn_cancel",boost::bind(&LLPanelGroup::onBtnCancel,this),NULL);
+
LLPanelGroupTab* panel_general = findChild<LLPanelGroupTab>("group_general_tab_panel");
LLPanelGroupTab* panel_roles = findChild<LLPanelGroupTab>("group_roles_tab_panel");
LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");
@@ -181,41 +194,30 @@ BOOL LLPanelGroup::postBuild()
if(panel_notices) mTabs.push_back(panel_notices);
if(panel_land) mTabs.push_back(panel_land);
- panel_general->setupCtrls(this);
+ if(panel_general)
+ panel_general->setupCtrls(this);
return TRUE;
}
+void LLPanelGroup::reposButton(const std::string& name)
+{
+ LLButton* button = findChild<LLButton>(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);
+}
+
void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent )
{
LLPanel::reshape(width, height, called_from_parent );
- LLRect btn_rect;
-
- LLButton* button = findChild<LLButton>("btn_apply");
- if(button)
- {
- btn_rect = button->getRect();
- btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
- button->setRect(btn_rect);
- }
-
- button = findChild<LLButton>("btn_create");
- if(button)
- {
- btn_rect = button->getRect();
- btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
- button->setRect(btn_rect);
- }
-
-
- button = findChild<LLButton>("btn_refresh");
- if(button)
- {
- btn_rect = button->getRect();
- btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
- button->setRect(btn_rect);
- }
+ reposButton("btn_apply");
+ reposButton("btn_create");
+ reposButton("btn_refresh");
+ reposButton("btn_cancel");
}
void LLPanelGroup::onBackBtnClick()
@@ -233,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)
@@ -247,33 +256,94 @@ void LLPanelGroup::onBtnApply(void* user_data)
LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
self->apply();
}
+void LLPanelGroup::onBtnJoin()
+{
+ lldebugs << "joining group: " << mID << llendl;
+
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
+
+ if (gdatap)
+ {
+ S32 cost = gdatap->mMembershipFee;
+ LLSD args;
+ args["COST"] = llformat("%d", cost);
+ LLSD payload;
+ payload["group_id"] = mID;
+
+ if (can_afford_transaction(cost))
+ {
+ LLNotifications::instance().add("JoinGroupCanAfford", args, payload, LLPanelGroup::joinDlgCB);
+ }
+ else
+ {
+ LLNotifications::instance().add("JoinGroupCannotAfford", args, payload);
+ }
+ }
+ else
+ {
+ llwarns << "LLGroupMgr::getInstance()->getGroupData(" << mID << ") was NULL" << llendl;
+ }
+}
+bool LLPanelGroup::joinDlgCB(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+
+ if (option == 1)
+ {
+ // user clicked cancel
+ return false;
+ }
+
+ LLGroupMgr::getInstance()->sendGroupMemberJoin(notification["payload"]["group_id"].asUUID());
+ return false;
+}
+
+void LLPanelGroup::onBtnCancel()
+{
+ onBackBtnClick();
+}
void LLPanelGroup::changed(LLGroupChange gc)
{
for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
(*it)->update(gc);
-
- LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
- if(gdatap)
- childSetValue("group_name", gdatap->mName);
+ update(gc);
}
void LLPanelGroup::notifyObservers()
{
- for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
- (*it)->update(GC_ALL);
+ changed(GC_ALL);
+}
+void LLPanelGroup::update(LLGroupChange gc)
+{
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
if(gdatap)
+ {
childSetValue("group_name", gdatap->mName);
-
-}
-
+ LLGroupData agent_gdatap;
+ bool is_member = gAgent.getGroupData(mID,agent_gdatap);
+ LLButton* btn_join = getChild<LLButton>("btn_join");
+ bool join_btn_visible = !is_member && gdatap->mOpenEnrollment;
+ btn_join->setVisible(join_btn_visible);
+ if(join_btn_visible)
+ {
+ LLStringUtil::format_map_t string_args;
+ string_args["[AMOUNT]"] = llformat("%d", gdatap->mMembershipFee);
+ std::string fee_buff = getString("group_join_btn", string_args);
+ btn_join->setLabelSelected(fee_buff);
+ btn_join->setLabelUnselected(fee_buff);
+ }
+ }
+}
void LLPanelGroup::setGroupID(const LLUUID& group_id)
{
+ std::string str_group_id;
+ group_id.toString(str_group_id);
+
LLGroupMgr::getInstance()->removeObserver(this);
mID = group_id;
LLGroupMgr::getInstance()->addObserver(this);
@@ -288,6 +358,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
LLButton* button_apply = findChild<LLButton>("btn_apply");
LLButton* button_refresh = findChild<LLButton>("btn_refresh");
LLButton* button_create = findChild<LLButton>("btn_create");
+ LLButton* button_join = findChild<LLButton>("btn_join");
+ LLButton* button_cancel = findChild<LLButton>("btn_cancel");
bool is_null_group_id = group_id == LLUUID::null;
@@ -295,8 +367,11 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
button_apply->setVisible(!is_null_group_id);
if(button_refresh)
button_refresh->setVisible(!is_null_group_id);
+
if(button_create)
button_create->setVisible(is_null_group_id);
+ if(button_cancel)
+ button_cancel->setVisible(!is_null_group_id);
getChild<LLUICtrl>("prepend_founded_by")->setVisible(!is_null_group_id);
@@ -307,6 +382,9 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
if(!tab_general || !tab_roles || !tab_notices || !tab_land)
return;
+
+ if(button_join)
+ button_join->setVisible(false);
if(is_null_group_id)//creating new group
{
@@ -323,6 +401,10 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
tab_roles->canOpenClose(false);
tab_notices->canOpenClose(false);
tab_land->canOpenClose(false);
+
+ getChild<LLUICtrl>("group_name")->setVisible(false);
+ getChild<LLUICtrl>("group_name_editor")->setVisible(true);
+
}
else
{
@@ -338,6 +420,9 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
tab_roles->canOpenClose(true);
tab_notices->canOpenClose(true);
tab_land->canOpenClose(true);
+
+ getChild<LLUICtrl>("group_name")->setVisible(true);
+ getChild<LLUICtrl>("group_name_editor")->setVisible(false);
}
}
@@ -395,11 +480,9 @@ void LLPanelGroup::draw()
void LLPanelGroup::refreshData()
{
LLGroupMgr::getInstance()->clearGroupData(getID());
-
- for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
- (*it)->activate();
-
+ setGroupID(getID());
+
// 5 second timeout
childDisable("btn_refresh");
mRefreshTimer.start();
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 6db6738d18..f2118a7244 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -91,12 +91,20 @@ public:
protected:
+ virtual void update(LLGroupChange gc);
+
void onBtnCreate();
void onBackBtnClick();
+ void onBtnJoin();
+ void onBtnCancel();
static void onBtnApply(void*);
static void onBtnRefresh(void*);
+ static bool joinDlgCB(const LLSD& notification, const LLSD& response);
+
+ void reposButton(const std::string& name);
+
protected:
bool apply(LLPanelGroupTab* tab);
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index f3893a104c..2e1d971995 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -50,7 +50,6 @@
#include "llnamelistctrl.h"
#include "llscrolllistitem.h"
#include "llspinctrl.h"
-#include "llstatusbar.h" // can_afford_transaction()
#include "lltextbox.h"
#include "lltexteditor.h"
#include "lltexturectrl.h"
@@ -96,15 +95,12 @@ BOOL LLPanelGroupGeneral::postBuild()
{
bool recurse = true;
- // General info
- mGroupNameEditor = getChild<LLLineEditor>("group_name_editor", recurse);
-
mEditCharter = getChild<LLTextEditor>("charter", recurse);
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));
}
@@ -194,7 +190,6 @@ BOOL LLPanelGroupGeneral::postBuild()
// If the group_id is null, then we are creating a new group
if (mGroupID.isNull())
{
- mGroupNameEditor->setEnabled(TRUE);
mEditCharter->setEnabled(TRUE);
mCtrlShowInGroupList->setEnabled(TRUE);
@@ -217,6 +212,7 @@ void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group)
mDefaultIconID = mInsignia->getImageAssetID();
}
mFounderName = panel_group->getChild<LLNameBox>("founder_name");
+ mGroupNameEditor = panel_group->getChild<LLLineEditor>("group_name_editor");
}
// static
@@ -298,56 +294,6 @@ void LLPanelGroupGeneral::onClickInfo(void *userdata)
}
// static
-void LLPanelGroupGeneral::onClickJoin(void *userdata)
-{
- LLPanelGroupGeneral *self = (LLPanelGroupGeneral *)userdata;
-
- if ( !self ) return;
-
- lldebugs << "joining group: " << self->mGroupID << llendl;
-
- LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(self->mGroupID);
-
- if (gdatap)
- {
- S32 cost = gdatap->mMembershipFee;
- LLSD args;
- args["COST"] = llformat("%d", cost);
- LLSD payload;
- payload["group_id"] = self->mGroupID;
-
- if (can_afford_transaction(cost))
- {
- LLNotifications::instance().add("JoinGroupCanAfford", args, payload, LLPanelGroupGeneral::joinDlgCB);
- }
- else
- {
- LLNotifications::instance().add("JoinGroupCannotAfford", args, payload);
- }
- }
- else
- {
- llwarns << "LLGroupMgr::getInstance()->getGroupData(" << self->mGroupID
- << ") was NULL" << llendl;
- }
-}
-
-// static
-bool LLPanelGroupGeneral::joinDlgCB(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
-
- if (option == 1)
- {
- // user clicked cancel
- return false;
- }
-
- LLGroupMgr::getInstance()->sendGroupMemberJoin(notification["payload"]["group_id"].asUUID());
- return false;
-}
-
-// static
void LLPanelGroupGeneral::openProfile(void* data)
{
LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
@@ -883,10 +829,13 @@ void LLPanelGroupGeneral::reset()
mComboActiveTitle->setVisible(false);
mInsignia->setImageAssetID(LLUUID::null);
+
+ mInsignia->setEnabled(true);
{
std::string empty_str = "";
mEditCharter->setText(empty_str);
+ mGroupNameEditor->setText(empty_str);
}
{
@@ -902,6 +851,7 @@ void LLPanelGroupGeneral::reset()
{
mComboMature->setEnabled(true);
mComboMature->setVisible( !gAgent.isTeen() );
+ mComboMature->selectFirstItem();
}
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index b828480a12..7e90e43cf9 100644
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -79,7 +79,6 @@ private:
static void onCommitUserOnly(LLUICtrl* ctrl, void* data);
static void onCommitTitle(LLUICtrl* ctrl, void* data);
static void onCommitEnrollment(LLUICtrl* ctrl, void* data);
- static void onClickJoin(void* userdata);
static void onClickInfo(void* userdata);
static void onReceiveNotices(LLUICtrl* ctrl, void* data);
static void openProfile(void* data);
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/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index 51cdc5af93..a7590ac1dd 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -82,6 +82,9 @@ void LLPanelIMControlPanel::onShareButtonClicked()
void LLPanelIMControlPanel::setID(const LLUUID& avatar_id)
{
+ // Disable "Add friend" button for friends.
+ childSetEnabled("add_friend_btn", !LLAvatarActions::isFriend(avatar_id));
+
getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(avatar_id);
}
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 9caa751854..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;
}
@@ -837,14 +838,22 @@ void LLPanelLogin::onClickConnect(void *)
std::string first = sInstance->childGetText("first_name_edit");
std::string last = sInstance->childGetText("last_name_edit");
- if (!first.empty() && !last.empty())
+ LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
+ std::string combo_text = combo->getSimple();
+
+ if (first.empty() || last.empty())
{
- // has both first and last name typed
- sInstance->mCallback(0, sInstance->mCallbackData);
+ LLNotifications::instance().add("MustHaveAccountToLogIn");
+ }
+ else if( (combo_text=="<Type region name>" || combo_text =="")
+ && LLURLSimString::sInstance.mSimString =="")
+ {
+ LLNotifications::instance().add("StartRegionEmpty");
}
else
{
- LLNotifications::instance().add("MustHaveAccountToLogIn");
+ // has both first and last name typed
+ sInstance->mCallback(0, sInstance->mCallbackData);
}
}
}
@@ -965,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 309a97a9f2..b2a0a01005 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -42,32 +42,53 @@
#include "llpanelpeople.h"
// newview
+#include "llaccordionctrltab.h"
#include "llagent.h"
#include "llavataractions.h"
#include "llavatarlist.h"
+#include "llavatarlistitem.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llfloateravatarpicker.h"
//#include "llfloaterminiinspector.h"
#include "llfriendcard.h"
#include "llgroupactions.h"
#include "llgrouplist.h"
+#include "llpanelpeoplemenus.h"
#include "llrecentpeople.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewermenu.h" // for gMenuHolder
#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";
static const std::string GROUP_TAB_NAME = "groups_panel";
static const std::string RECENT_TAB_NAME = "recent_panel";
+/** Comparator for comparing avatar items by last interaction date */
+class LLAvatarItemRecentComparator : public LLAvatarItemComparator
+{
+public:
+ LLAvatarItemRecentComparator() {};
+ virtual ~LLAvatarItemRecentComparator() {};
+
+protected:
+ virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const
+ {
+ LLRecentPeople& people = LLRecentPeople::instance();
+ const LLDate& date1 = people.getDate(avatar_item1->getAvatarId());
+ const LLDate& date2 = people.getDate(avatar_item2->getAvatarId());
+
+ //older comes first
+ return date1 > date2;
+ }
+};
+
+static const LLAvatarItemRecentComparator RECENT_COMPARATOR;
+
static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people");
//=============================================================================
@@ -78,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)
{
@@ -89,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.
@@ -106,9 +117,9 @@ public:
virtual void setActive(bool) {}
protected:
- bool updateList(U32 mask = 0)
+ void updateList()
{
- return mCallback(mask);
+ mCallback();
}
callback_t mCallback;
@@ -123,6 +134,11 @@ public:
{
mEventTimer.stop();
}
+
+ virtual BOOL tick() // from LLEventTimer
+ {
+ return FALSE;
+ }
};
/**
@@ -154,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 -
@@ -174,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;
}
@@ -299,74 +308,15 @@ private:
/**
* Updates the recent people list (those the agent has recently interacted with).
*/
-class LLRecentListUpdater : public LLAvatarListUpdater
+class LLRecentListUpdater : public LLAvatarListUpdater, public boost::signals2::trackable
{
LOG_CLASS(LLRecentListUpdater);
public:
LLRecentListUpdater(callback_t cb)
- : LLAvatarListUpdater(cb, RECENT_LIST_UPDATE_DELAY)
+ : LLAvatarListUpdater(cb, 0)
{
- 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()
- {
- 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));
}
};
@@ -380,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()
@@ -393,26 +343,29 @@ LLPanelPeople::~LLPanelPeople()
delete mNearbyListUpdater;
delete mFriendListUpdater;
delete mRecentListUpdater;
- delete mGroupListUpdater;
LLView::deleteViewByHandle(mGroupPlusMenuHandle);
LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);
LLView::deleteViewByHandle(mFriendsViewSortMenuHandle);
+ LLView::deleteViewByHandle(mGroupsViewSortMenuHandle);
LLView::deleteViewByHandle(mRecentViewSortMenuHandle);
}
-void onAvatarListTmpDoubleClicked(LLAvatarListTmp* list)
-{
- LLUUID clicked_id = list->getCurrentID();
- if (clicked_id.isNull())
+void LLPanelPeople::onFriendsAccordionExpandedCollapsed(const LLSD& param, LLAvatarList* avatar_list)
+{
+ if(!avatar_list)
+ {
+ llerrs << "Bad parameter" << llendl;
return;
+ }
-#if 0 // SJB: Useful for testing, but not currently functional or to spec
- LLAvatarActions::showProfile(clicked_id);
-#else // spec says open IM window
- LLAvatarActions::startIM(clicked_id);
-#endif
+ bool expanded = param.asBoolean();
+
+ if(!expanded)
+ {
+ avatar_list->resetSelection();
+ }
}
BOOL LLPanelPeople::postBuild()
@@ -427,11 +380,22 @@ BOOL LLPanelPeople::postBuild()
mOnlineFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatars_online");
mAllFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatars_all");
+ mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));
+ mAllFriendList->setNoItemsCommentText(getString("no_friends"));
mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
+ mNearbyList->setNoItemsCommentText(getString("no_one_near"));
+
+ mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
+ mRecentList->setNoItemsCommentText(getString("no_people"));
- mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarListTmp>("avatar_list");
mGroupList = getChild<LLGroupList>("group_list");
+ mGroupList->setNoItemsCommentText(getString("no_groups"));
+
+ mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
+ mRecentList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
+
+ mRecentList->setComparator(&RECENT_COMPARATOR);
LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME);
groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked, this));
@@ -445,15 +409,24 @@ BOOL LLPanelPeople::postBuild()
mOnlineFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mOnlineFriendList));
mAllFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mAllFriendList));
mNearbyList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mNearbyList));
- mRecentList->setDoubleClickCallback(boost::bind(onAvatarListTmpDoubleClicked, mRecentList));
+ mRecentList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mRecentList));
+
mOnlineFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mOnlineFriendList));
mAllFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mAllFriendList));
mNearbyList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mNearbyList));
- mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
+ mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mRecentList));
mGroupList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this));
mGroupList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
+ LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>("tab_all");
+ accordion_tab->setDropDownStateChangedCallback(
+ boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _2, mAllFriendList));
+
+ accordion_tab = getChild<LLAccordionCtrlTab>("tab_online");
+ accordion_tab->setDropDownStateChangedCallback(
+ boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _2, mOnlineFriendList));
+
buttonSetAction("view_profile_btn", boost::bind(&LLPanelPeople::onViewProfileButtonClicked, this));
buttonSetAction("add_friend_btn", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
buttonSetAction("group_info_btn", boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this));
@@ -464,8 +437,9 @@ 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));
// Must go after setting commit callback and initializing all pointers to children.
mTabContainer->selectTabByName(FRIENDS_TAB_NAME);
@@ -476,6 +450,7 @@ BOOL LLPanelPeople::postBuild()
registrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2));
registrar.add("People.Friends.ViewSort.Action", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked, this, _2));
registrar.add("People.Nearby.ViewSort.Action", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked, this, _2));
+ registrar.add("People.Groups.ViewSort.Action", boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked, this, _2));
registrar.add("People.Recent.ViewSort.Action", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked, this, _2));
LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
@@ -489,134 +464,79 @@ BOOL LLPanelPeople::postBuild()
if(friend_view_sort)
mFriendsViewSortMenuHandle = friend_view_sort->getHandle();
+ LLMenuGL* group_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_groups_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if(group_view_sort)
+ mGroupsViewSortMenuHandle = group_view_sort->getHandle();
+
LLMenuGL* recent_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_recent_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if(recent_view_sort)
mRecentViewSortMenuHandle = recent_view_sort->getHandle();
-
-
- // Perform initial update.
- mFriendListUpdater->forceUpdate();
- mRecentListUpdater->forceUpdate();
- mGroupListUpdater->forceUpdate();
- mRecentListUpdater->forceUpdate();
+ // call this method in case some list is empty and buttons can be in inconsistent state
+ updateButtons();
return TRUE;
}
-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
-
- bool have_names = mGroupList->update(mFilterSubString);
-
- if (mGroupList->isEmpty())
- mGroupList->setCommentText(getString("no_groups"));
-
- return have_names;
-}
-
-bool LLPanelPeople::filterFriendList()
-{
- 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);
-
- if (mOnlineFriendVec.size() == 0)
- mOnlineFriendList->setCommentText(getString("no_friends_online"));
-
- if (mAllFriendVec.size() == 0)
- mAllFriendList->setCommentText(getString("no_friends"));
+ 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);
+ }
- return have_names;
+ mOnlineFriendList->setDirty();
+ mAllFriendList->setDirty();
}
-bool LLPanelPeople::filterNearbyList()
+void LLPanelPeople::updateNearbyList()
{
- bool have_names = mNearbyList->update(mNearbyVec, mFilterSubString);
-
- if (mNearbyVec.size() == 0)
- mNearbyList->setCommentText(getString("no_one_near"));
+ if (!mNearbyList)
+ return;
- 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)
- return mRecentList->update(mRecentVec, mFilterSubString);
-
- mRecentList->setCommentText(getString("no_people"));
+ return;
- return true;
+ LLRecentPeople::instance().get(mRecentList->getIDs());
+ mRecentList->setDirty();
}
void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
@@ -664,12 +584,12 @@ void LLPanelPeople::updateButtons()
if (group_tab_active)
{
- bool item_selected = mGroupList->getFirstSelected() != NULL;
+ bool item_selected = mGroupList->getSelectedItem() != NULL;
bool cur_group_active = true;
if (item_selected)
{
- selected_id = mGroupList->getCurrentID();
+ selected_id = mGroupList->getSelectedUUID();
cur_group_active = (gAgent.getGroupID() == selected_id);
}
@@ -714,20 +634,20 @@ LLUUID LLPanelPeople::getCurrentItemID() const
{
LLUUID cur_online_friend;
- if ((cur_online_friend = mOnlineFriendList->getCurrentID()).notNull())
+ if ((cur_online_friend = mOnlineFriendList->getSelectedUUID()).notNull())
return cur_online_friend;
- return mAllFriendList->getCurrentID();
+ return mAllFriendList->getSelectedUUID();
}
if (cur_tab == NEARBY_TAB_NAME)
- return mNearbyList->getCurrentID();
+ return mNearbyList->getSelectedUUID();
if (cur_tab == RECENT_TAB_NAME)
- return mRecentList->getCurrentID();
+ return mRecentList->getSelectedUUID();
if (cur_tab == GROUP_TAB_NAME)
- return mGroupList->getCurrentID();
+ return mGroupList->getSelectedUUID();
llassert(0 && "unknown tab selected");
return LLUUID::null;
@@ -785,13 +705,12 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
LLStringUtil::toUpper(mFilterSubString);
LLStringUtil::trimHead(mFilterSubString);
- // Apply new filter to all tabs.
- filterNearbyList();
- filterFriendList();
- filterRecentList();
- updateGroupList();
-
- updateButtons();
+ // Apply new filter.
+ mNearbyList->setNameFilter(mFilterSubString);
+ mOnlineFriendList->setNameFilter(mFilterSubString);
+ mAllFriendList->setNameFilter(mFilterSubString);
+ mRecentList->setNameFilter(mFilterSubString);
+ mGroupList->setNameFilter(mFilterSubString);
}
void LLPanelPeople::onTabSelected(const LLSD& param)
@@ -808,7 +727,7 @@ void LLPanelPeople::onTabSelected(const LLSD& param)
void LLPanelPeople::onAvatarListDoubleClicked(LLAvatarList* list)
{
- LLUUID clicked_id = list->getCurrentID();
+ LLUUID clicked_id = list->getSelectedUUID();
if (clicked_id.isNull())
return;
@@ -826,9 +745,9 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)
if (getActiveTabName() == FRIENDS_TAB_NAME)
{
if (list == mOnlineFriendList)
- mAllFriendList->deselectAllItems(TRUE);
+ mAllFriendList->resetSelection(true);
else if (list == mAllFriendList)
- mOnlineFriendList->deselectAllItems(TRUE);
+ mOnlineFriendList->resetSelection(true);
else
llassert(0 && "commit on unknown friends list");
}
@@ -890,7 +809,7 @@ void LLPanelPeople::onImButtonClicked()
void LLPanelPeople::onActivateButtonClicked()
{
- LLGroupActions::activate(mGroupList->getCurrentID());
+ LLGroupActions::activate(mGroupList->getSelectedUUID());
}
// static
@@ -903,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();
-
- return have_names;
-}
-
void LLPanelPeople::onGroupPlusButtonClicked()
{
LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
@@ -957,6 +865,17 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata)
{
}
}
+
+void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata)
+{
+ std::string chosen_item = userdata.asString();
+
+ if (chosen_item == "show_icons")
+ {
+ mGroupList->toggleIcons();
+ }
+}
+
void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)
{
std::string chosen_item = userdata.asString();
@@ -966,6 +885,7 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)
}
else if (chosen_item == "sort_name")
{
+ mNearbyList->sortByName();
}
else if (chosen_item == "view_icons")
{
@@ -978,11 +898,14 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)
{
std::string chosen_item = userdata.asString();
- if (chosen_item == "sort_most")
+ if (chosen_item == "sort_recent")
{
- }
+ mRecentList->setComparator(&RECENT_COMPARATOR);
+ mRecentList->sort();
+ }
else if (chosen_item == "sort_name")
{
+ mRecentList->sortByName();
}
else if (chosen_item == "view_icons")
{
@@ -1008,6 +931,7 @@ void LLPanelPeople::onMoreButtonClicked()
{
// *TODO: not implemented yet
}
+
void LLPanelPeople::onFriendsViewSortButtonClicked()
{
LLMenuGL* menu = (LLMenuGL*)mFriendsViewSortMenuHandle.get();
@@ -1015,6 +939,15 @@ void LLPanelPeople::onFriendsViewSortButtonClicked()
return;
showGroupMenu(menu);
}
+
+void LLPanelPeople::onGroupsViewSortButtonClicked()
+{
+ LLMenuGL* menu = (LLMenuGL*)mGroupsViewSortMenuHandle.get();
+ if (!menu)
+ return;
+ showGroupMenu(menu);
+}
+
void LLPanelPeople::onRecentViewSortButtonClicked()
{
LLMenuGL* menu = (LLMenuGL*)mRecentViewSortMenuHandle.get();
@@ -1022,6 +955,7 @@ void LLPanelPeople::onRecentViewSortButtonClicked()
return;
showGroupMenu(menu);
}
+
void LLPanelPeople::onNearbyViewSortButtonClicked()
{
LLMenuGL* menu = (LLMenuGL*)mNearbyViewSortMenuHandle.get();
@@ -1041,4 +975,3 @@ void LLPanelPeople::onOpen(const LLSD& key)
else
reSelectedCurrentTab();
}
-
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index c0c2f70614..de27814388 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -40,7 +40,6 @@
class LLFilterEditor;
class LLTabContainer;
class LLAvatarList;
-class LLAvatarListTmp;
class LLGroupList;
class LLPanelPeople : public LLPanel
@@ -59,14 +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 updateFriendList();
+ void updateNearbyList();
+ void updateRecentList();
+
void updateButtons();
const std::string& getActiveTabName() const;
LLUUID getCurrentItemID() const;
@@ -97,6 +92,7 @@ private:
void onRecentViewSortButtonClicked();
void onNearbyViewSortButtonClicked();
void onFriendsViewSortButtonClicked();
+ void onGroupsViewSortButtonClicked();
void onAvatarListDoubleClicked(LLAvatarList* list);
void onAvatarListCommitted(LLAvatarList* list);
void onGroupPlusButtonClicked();
@@ -105,46 +101,36 @@ private:
void onFriendsViewSortMenuItemClicked(const LLSD& userdata);
void onNearbyViewSortMenuItemClicked(const LLSD& userdata);
+ void onGroupsViewSortMenuItemClicked(const LLSD& userdata);
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,
void*);
+ void onFriendsAccordionExpandedCollapsed(const LLSD& param, LLAvatarList* avatar_list);
+
LLFilterEditor* mFilterEditor;
LLTabContainer* mTabContainer;
LLAvatarList* mOnlineFriendList;
LLAvatarList* mAllFriendList;
LLAvatarList* mNearbyList;
- LLAvatarListTmp* mRecentList;
+ LLAvatarList* mRecentList;
LLGroupList* mGroupList;
LLHandle<LLView> mGroupPlusMenuHandle;
LLHandle<LLView> mNearbyViewSortMenuHandle;
LLHandle<LLView> mFriendsViewSortMenuHandle;
+ LLHandle<LLView> mGroupsViewSortMenuHandle;
LLHandle<LLView> mRecentViewSortMenuHandle;
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/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
new file mode 100644
index 0000000000..0e88058bb1
--- /dev/null
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -0,0 +1,148 @@
+/**
+ * @file llpanelpeoplemenus.h
+ * @brief Menus used by the side tray "People" panel
+ *
+ * $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"
+
+// libs
+#include "llmenugl.h"
+#include "lluictrlfactory.h"
+
+#include "llpanelpeoplemenus.h"
+
+// newview
+#include "llagentdata.h" // for gAgentID
+#include "llavataractions.h"
+#include "llviewermenu.h" // for gMenuHolder
+
+namespace LLPanelPeopleMenus
+{
+
+NearbyMenu gNearbyMenu;
+
+//== ContextMenu ==============================================================
+
+ContextMenu::ContextMenu()
+: mMenu(NULL)
+{
+}
+
+void ContextMenu::show(LLView* spawning_view, const LLUUID& id, 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;
+ }
+
+ mID = id;
+ mMenu = createMenu();
+ mMenu->show(x, y);
+ LLMenuGL::showPopup(spawning_view, mMenu, x, y);
+}
+
+//== NearbyMenu ===============================================================
+
+LLContextMenu* NearbyMenu::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;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+ registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, mID));
+ registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mID));
+ registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, mID));
+ registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startIM, mID)); // *TODO: unimplemented
+ registrar.add("Avatar.OfferTeleport", boost::bind(&NearbyMenu::offerTeleport, this));
+ registrar.add("Avatar.ShowOnMap", boost::bind(&LLAvatarActions::startIM, mID)); // *TODO: unimplemented
+ registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::startIM, mID)); // *TODO: unimplemented
+ registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mID));
+ registrar.add("Avatar.BlockUnblock", boost::bind(&LLAvatarActions::toggleBlock, mID));
+
+ enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2));
+ enable_registrar.add("Avatar.CheckItem", boost::bind(&NearbyMenu::checkContextMenuItem, this, _2));
+
+ // create the context menu from the XUI
+ return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+ "menu_people_nearby.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+}
+
+bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+
+ if (item == std::string("can_block"))
+ {
+ std::string firstname, lastname;
+ gCacheName->getName(mID, firstname, lastname);
+ bool is_linden = !LLStringUtil::compareStrings(lastname, "Linden");
+ bool is_self = mID == gAgentID;
+ return !is_self && !is_linden;
+ }
+ else if (item == std::string("can_add"))
+ {
+ return !LLAvatarActions::isFriend(mID);
+ }
+ else if (item == std::string("can_delete"))
+ {
+ return LLAvatarActions::isFriend(mID);
+ }
+
+ return false;
+}
+
+bool NearbyMenu::checkContextMenuItem(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+
+ if (item == std::string("is_blocked"))
+ {
+ return LLAvatarActions::isBlocked(mID);
+ }
+
+ return false;
+}
+
+void NearbyMenu::offerTeleport()
+{
+ // boost::bind cannot recognize overloaded method LLAvatarActions::offerTeleport(),
+ // so we have to use a wrapper.
+ LLAvatarActions::offerTeleport(mID);
+}
+
+} // namespace LLPanelPeopleMenus
diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h
new file mode 100644
index 0000000000..0012ac38f8
--- /dev/null
+++ b/indra/newview/llpanelpeoplemenus.h
@@ -0,0 +1,82 @@
+/**
+ * @file llpanelpeoplemenus.h
+ * @brief Menus used by the side tray "People" panel
+ *
+ * $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_LLPANELPEOPLEMENUS_H
+#define LL_LLPANELPEOPLEMENUS_H
+
+#include "llavatarlistitem.h"
+
+namespace LLPanelPeopleMenus
+{
+
+/**
+ * Base context menu.
+ */
+class ContextMenu : public LLAvatarListItem::ContextMenu
+{
+public:
+ ContextMenu();
+ virtual ~ContextMenu() {}
+
+ /**
+ * Show the menu at specified coordinates.
+ *
+ * @param id either avatar or group id
+ */
+ /*virtual*/ void show(LLView* spawning_view, const LLUUID& id, S32 x, S32 y);
+
+protected:
+
+ virtual LLContextMenu* createMenu() = 0;
+
+ LLUUID mID;
+ LLContextMenu* mMenu;
+};
+
+/**
+ * Menu used in the nearby people list.
+ */
+class NearbyMenu : public ContextMenu
+{
+public:
+ /*virtual*/ LLContextMenu* createMenu();
+private:
+ bool enableContextMenuItem(const LLSD& userdata);
+ bool checkContextMenuItem(const LLSD& userdata);
+ void offerTeleport();
+};
+
+extern NearbyMenu gNearbyMenu;
+
+} // namespace LLPanelPeopleMenus
+
+#endif // LL_LLPANELPEOPLEMENUS_H
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 9ae58d1cb6..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"
@@ -64,6 +66,7 @@
#define LABEL_PICK = "Pick"
#define LABEL_CHANGES = "Changes"
+std::string SET_LOCATION_NOTICE("(will update after save)");
LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */)
: LLPanel(), LLAvatarPropertiesObserver(), LLRemoteParcelInfoObserver(),
@@ -71,7 +74,9 @@ LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */)
mSnapshotCtrl(NULL),
mPickId(LLUUID::null),
mCreatorId(LLUUID::null),
- mDataReceived(FALSE)
+ mDataReceived(FALSE),
+ mIsPickNew(false),
+ mLocationChanged(false)
{
if (edit_mode)
{
@@ -121,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));
@@ -171,7 +186,7 @@ void LLPanelPick::init(LLPickData *pick_data)
setPickName(pick_data->name);
setPickDesc(pick_data->desc);
- setPickLocation(pick_data->location_text);
+
mSnapshotCtrl->setImageAssetID(pick_data->snapshot_id);
//*HACK see reset() where the texture control was set to FALSE
@@ -180,27 +195,45 @@ void LLPanelPick::init(LLPickData *pick_data)
mPosGlobal = pick_data->pos_global;
mSimName = pick_data->sim_name;
mParcelId = pick_data->parcel_id;
+
+ setPickLocation(createLocationText(pick_data->user_name, pick_data->original_name,
+ pick_data->sim_name, pick_data->pos_global));
}
-// Fill in some reasonable defaults for a new pick.
-void LLPanelPick::createNewPick()
+void LLPanelPick::prepareNewPick(const LLVector3d pos_global,
+ const std::string& name,
+ const std::string& desc,
+ const LLUUID& snapshot_id,
+ const LLUUID& parcel_id)
{
mPickId.generate();
mCreatorId = gAgent.getID();
- mPosGlobal = gAgent.getPositionGlobal();
+ mPosGlobal = pos_global;
+ setPickName(name);
+ setPickDesc(desc);
+ mSnapshotCtrl->setImageAssetID(snapshot_id);
+ mParcelId = parcel_id;
+ setPickLocation(createLocationText(std::string(""), SET_LOCATION_NOTICE, name, pos_global));
+
+ childSetLabelArg(XML_BTN_SAVE, SAVE_BTN_LABEL, std::string("Pick"));
+
+ mIsPickNew = true;
+}
+
+// Fill in some reasonable defaults for a new pick.
+void LLPanelPick::prepareNewPick()
+{
// Try to fill in the current parcel
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if (parcel)
{
- setPickName(parcel->getName());
- setPickDesc(parcel->getDesc());
- mSnapshotCtrl->setImageAssetID(parcel->getSnapshotID());
+ prepareNewPick(gAgent.getPositionGlobal(),
+ parcel->getName(),
+ parcel->getDesc(),
+ parcel->getSnapshotID(),
+ parcel->getID());
}
-
- sendUpdate();
-
- childSetLabelArg(XML_BTN_SAVE, SAVE_BTN_LABEL, std::string("Pick"));
}
/*virtual*/ void LLPanelPick::processProperties(void* data, EAvatarProcessorType type)
@@ -235,6 +268,15 @@ void LLPanelPick::setEditMode( BOOL edit_mode )
deleteAllChildren();
+ // *WORKAROUND: for EXT-931. Children are created for both XML_PANEL_EDIT_PICK & XML_PANEL_PICK_INFO files
+ // The reason is in LLPanel::initPanelXML called from the LLUICtrlFactory::buildPanel().
+ // It creates children from the xml file stored while previous initializing in the "mXMLFilename" member
+ // and then in creates children from the parameters passed from the LLUICtrlFactory::buildPanel().
+ // Xml filename is stored after LLPanel::initPanelXML is called (added with export-from-ll/viewer-2-0, r1594 into LLUICtrlFactory::buildPanel & LLUICtrlFactory::buildFloater)
+ // In case panel creates children from the different xml files they appear from both files.
+ // So, let clear xml filename related to this instance.
+ setXMLFilename("");
+
if (edit_mode)
{
LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_EDIT_PICK);
@@ -258,6 +300,60 @@ 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
+//////////////////////////////////////////////////////////////////////////
+
+//static
+std::string LLPanelPick::createLocationText(const std::string& owner_name, const std::string& original_name,
+ const std::string& sim_name, const LLVector3d& pos_global)
+{
+ std::string location_text;
+ location_text.append(owner_name);
+ if (!original_name.empty())
+ {
+ if (!location_text.empty()) location_text.append(", ");
+ location_text.append(original_name);
+
+ }
+ if (!sim_name.empty())
+ {
+ if (!location_text.empty()) location_text.append(", ");
+ location_text.append(sim_name);
+ }
+
+ if (!location_text.empty()) location_text.append(" ");
+
+ if (!pos_global.isNull())
+ {
+ S32 region_x = llround((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = llround((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = llround((F32)pos_global.mdV[VZ]);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ }
+ return location_text;
+}
+
void LLPanelPick::setPickName(std::string name)
{
if (mEditMode)
@@ -288,7 +384,7 @@ void LLPanelPick::setPickDesc(std::string desc)
mDesc = desc;
}
-void LLPanelPick::setPickLocation(std::string location)
+void LLPanelPick::setPickLocation(const std::string& location)
{
childSetWrappedText(XML_LOCATION, location);
@@ -375,6 +471,12 @@ void LLPanelPick::onClickCancel()
{
if (!mEditMode) return;
+ if (mIsPickNew)
+ {
+ mBackCb(this, LLSD());
+ return;
+ }
+
LLUUID pick_id = mPickId;
LLUUID creator_id = mCreatorId;
reset();
@@ -385,29 +487,37 @@ void LLPanelPick::onClickCancel()
void LLPanelPick::onClickSet()
{
if (!mEditMode) return;
- if (!mDataReceived) return;
+ if (!mIsPickNew && !mDataReceived) return;
// Save location for later.
mPosGlobal = gAgent.getPositionGlobal();
- S32 region_x = llround((F32)mPosGlobal.mdV[VX]) % REGION_WIDTH_UNITS;
- S32 region_y = llround((F32)mPosGlobal.mdV[VY]) % REGION_WIDTH_UNITS;
- S32 region_z = llround((F32)mPosGlobal.mdV[VZ]);
-
- std::string location_text = "(will update after save), ";
- location_text.append(mSimName);
- location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ mParcelId = parcel->getID();
+ mSimName = parcel->getName();
+ }
+ setPickLocation(createLocationText(std::string(""), SET_LOCATION_NOTICE, mSimName, mPosGlobal));
- setPickLocation(location_text);
+ mLocationChanged = true;
+ enableSaveButton(TRUE);
}
// static
void LLPanelPick::onClickSave()
{
if (!mEditMode) return;
- if (!mDataReceived) return;
+ if (!mIsPickNew && !mDataReceived) return;
sendUpdate();
+
+ if (mIsPickNew)
+ {
+ mBackCb(this, LLSD());
+ return;
+ }
+
setEditMode(FALSE);
}
@@ -478,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 2cd4706dfe..82cba72bc4 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -56,9 +56,14 @@ public:
/*virtual*/ BOOL postBuild();
- // Create a new pick, including creating an id, giving a sane
- // initial position, etc.
- void createNewPick();
+ // Prepares a new pick, including creating an id, giving a sane
+ // initial position, etc (saved on clicking Save Pick button - onClickSave callback).
+ void prepareNewPick();
+ void prepareNewPick(const LLVector3d pos_global,
+ const std::string& name,
+ const std::string& desc,
+ const LLUUID& snapshot_id,
+ const LLUUID& parcel_id);
//initializes the panel with data of the pick with id = pick_id
//owned by the avatar with id = creator_id
@@ -69,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)
@@ -87,9 +94,16 @@ public:
protected:
+ /**
+ * "Location text" is actually the owner name, the original
+ * name that owner gave the parcel, and the location.
+ */
+ static std::string createLocationText(const std::string& owner_name, const std::string& original_name,
+ const std::string& sim_name, const LLVector3d& pos_global);
+
void setPickName(std::string name);
void setPickDesc(std::string desc);
- void setPickLocation(std::string location);
+ void setPickLocation(const std::string& location);
std::string getPickName();
std::string getPickDesc();
@@ -116,10 +130,13 @@ protected:
void onClickSave();
void onClickCancel();
+ void enableSaveButton(bool enable);
+
protected:
BOOL mEditMode;
LLTextureCtrl* mSnapshotCtrl;
BOOL mDataReceived;
+ bool mIsPickNew;
LLUUID mPickId;
LLUUID mCreatorId;
@@ -133,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 d374d24316..e74afba25a 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -34,6 +34,7 @@
#include "llagent.h"
#include "llavatarconstants.h"
+#include "llflatlistview.h"
#include "lltexturectrl.h"
#include "llviewergenericmessage.h" // send_generic_message
#include "llmenugl.h"
@@ -45,8 +46,6 @@
#include "llpanelavatar.h"
#include "llpanelprofile.h"
#include "llpanelpick.h"
-#include "llscrollcontainer.h"
-#include "lllistctrl.h"
static const std::string XML_BTN_NEW = "new_btn";
static const std::string XML_BTN_DELETE = "trash_btn";
@@ -127,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));
}
@@ -148,7 +146,7 @@ LLPickItem* LLPanelPicks::getSelectedPickItem()
BOOL LLPanelPicks::postBuild()
{
- mPicksList = getChild<LLListCtrl>("picks_list");
+ mPicksList = getChild<LLFlatListView>("picks_list");
childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
@@ -199,6 +197,11 @@ void LLPanelPicks::onOpen(const LLSD& key)
mPopupMenu->setItemVisible("pick_separator", TRUE);
}
+ if(getAvatarId() != key.asUUID())
+ {
+ mPicksList->goToTop();
+ }
+
LLPanelProfileTab::onOpen(key);
}
@@ -256,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();
@@ -314,7 +319,7 @@ void LLPanelPicks::onClickNew()
{
buildPickPanel();
mPickPanel->setEditMode(TRUE);
- mPickPanel->createNewPick();
+ mPickPanel->prepareNewPick();
getProfilePanel()->togglePanel(mPickPanel);
}
@@ -386,7 +391,6 @@ void LLPickItem::init(LLPickData* pick_data)
setPickDesc(pick_data->desc);
setSnapshotId(pick_data->snapshot_id);
mPosGlobal = pick_data->pos_global;
- mLocation = pick_data->location_text;
LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
picture->setImageAssetID(pick_data->snapshot_id);
@@ -434,11 +438,6 @@ const LLVector3d& LLPickItem::getPosGlobal()
return mPosGlobal;
}
-const std::string& LLPickItem::getLocation()
-{
- return mLocation;
-}
-
const std::string LLPickItem::getDescription()
{
return childGetValue("picture_descr").asString();
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 97e8e607c8..7ebdc3089c 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -48,7 +48,7 @@ class LLPanelPick;
class LLAgent;
class LLMenuGL;
class LLPickItem;
-class LLListCtrl;
+class LLFlatListView;
class LLPanelPicks
: public LLPanelProfileTab
@@ -100,14 +100,14 @@ 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();
LLMenuGL* mPopupMenu;
LLPanelProfile* mProfilePanel;
LLPanelPick* mPickPanel;
- LLListCtrl* mPicksList;
+ LLFlatListView* mPicksList;
};
class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver
@@ -142,8 +142,6 @@ public:
const LLVector3d& getPosGlobal();
- const std::string& getLocation();
-
const std::string getDescription();
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
@@ -167,7 +165,6 @@ protected:
bool mNeedData;
std::string mPickName;
- std::string mLocation;
};
#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 793c25455d..cbc5ca7e94 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -44,6 +44,7 @@
#include "llqueryflags.h"
#include "llbutton.h"
+#include "lliconctrl.h"
#include "lllineeditor.h"
#include "llscrollcontainer.h"
#include "lltextbox.h"
@@ -55,6 +56,7 @@
#include "llfloaterworldmap.h"
#include "llinventorymodel.h"
#include "lllandmarkactions.h"
+#include "llpanelpick.h"
#include "lltexturectrl.h"
#include "llviewerinventory.h"
#include "llviewerparcelmgr.h"
@@ -69,6 +71,7 @@ LLPanelPlaceInfo::LLPanelPlaceInfo()
: LLPanel(),
mParcelID(),
mRequestedID(),
+ mPosRegion(),
mLandmarkID(),
mMinHeight(0),
mScrollingPanel(NULL),
@@ -89,6 +92,8 @@ BOOL LLPanelPlaceInfo::postBuild()
mTitle = getChild<LLTextBox>("panel_title");
mCurrentTitle = mTitle->getText();
+ mForSaleIcon = getChild<LLIconCtrl>("icon_for_sale");
+
// Since this is only used in the directory browser, always
// disable the snapshot control. Otherwise clicking on it will
// open a texture picker.
@@ -252,6 +257,8 @@ void LLPanelPlaceInfo::resetLocation()
mParcelID.setNull();
mRequestedID.setNull();
mLandmarkID.setNull();
+ mPosRegion.clearVec();
+ mForSaleIcon->setVisible(FALSE);
std::string not_available = getString("not_available");
mMaturityRatingText->setValue(not_available);
mParcelOwner->setValue(not_available);
@@ -450,12 +457,27 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
//update for_sale banner, here we should use DFQ_FOR_SALE instead of PF_FOR_SALE
//because we deal with remote parcel response format
- bool isForSale = (parcel_data.flags & DFQ_FOR_SALE)? TRUE : FALSE;
- getChild<LLIconCtrl>("icon_for_sale")->setVisible(isForSale);
+ bool isForSale = (parcel_data.flags & DFQ_FOR_SALE) &&
+ mInfoType == AGENT ? TRUE : FALSE;
+ mForSaleIcon->setVisible(isForSale);
+
+ S32 region_x;
+ S32 region_y;
+ S32 region_z;
- S32 region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
- S32 region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
- S32 region_z = llround(parcel_data.global_z);
+ // If the region position is zero, grab position from the global
+ if(mPosRegion.isExactlyZero())
+ {
+ region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
+ region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
+ region_z = llround(parcel_data.global_z);
+ }
+ else
+ {
+ region_x = llround(mPosRegion.mV[VX]);
+ region_y = llround(mPosRegion.mV[VY]);
+ region_z = llround(mPosRegion.mV[VZ]);
+ }
std::string name = getString("not_available");
if (!parcel_data.sim_name.empty())
@@ -488,15 +510,15 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLUUID& region_id,
if (!region)
return;
+ mPosRegion.setVec((F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS),
+ (F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS),
+ (F32)pos_global.mdV[VZ]);
+
LLSD body;
std::string url = region->getCapability("RemoteParcelRequest");
if (!url.empty())
{
- F32 region_x = (F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS);
- F32 region_y = (F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS);
- LLVector3 pos_region(region_x, region_y, (F32)pos_global.mdV[VZ]);
-
- body["location"] = ll_sd_from_vector3(pos_region);
+ body["location"] = ll_sd_from_vector3(mPosRegion);
if (!region_id.isNull())
{
body["region_id"] = region_id;
@@ -537,20 +559,22 @@ void LLPanelPlaceInfo::displaySelectedParcelInfo(LLParcel* parcel,
{
case SIM_ACCESS_MATURE:
parcel_data.flags = 0x1;
+ break;
case SIM_ACCESS_ADULT:
parcel_data.flags = 0x2;
+ break;
default:
parcel_data.flags = 0;
}
parcel_data.desc = parcel->getDesc();
parcel_data.name = parcel->getName();
- parcel_data.sim_name = gAgent.getRegion()->getName();
+ parcel_data.sim_name = region->getName();
parcel_data.snapshot_id = parcel->getSnapshotID();
- parcel_data.global_x = pos_global.mdV[0];
- parcel_data.global_y = pos_global.mdV[1];
- parcel_data.global_z = pos_global.mdV[2];
+ parcel_data.global_x = pos_global.mdV[VX];
+ parcel_data.global_y = pos_global.mdV[VY];
+ parcel_data.global_z = pos_global.mdV[VZ];
std::string on = getString("on");
std::string off = getString("off");
@@ -854,30 +878,19 @@ void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id)
folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK));
}
-void LLPanelPlaceInfo::createPick(const LLVector3d& global_pos)
+void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPick* pick_panel)
{
- LLPickData pick_data;
-
- pick_data.agent_id = gAgent.getID();
- pick_data.session_id = gAgent.getSessionID();
- pick_data.pick_id = LLUUID::generateNewID();
- pick_data.creator_id = gAgentID;
-
- //legacy var needs to be deleted
- pick_data.top_pick = FALSE;
- pick_data.parcel_id = mParcelID;
- pick_data.name = mParcelName->getText();
- if (pick_data.name.empty())
+ std::string name = mParcelName->getText();
+ if (name.empty())
{
- pick_data.name = mRegionName->getText();
+ name = mRegionName->getText();
}
- pick_data.desc = mDescEditor->getText();
- pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
- pick_data.pos_global = global_pos;
- pick_data.sort_order = 0;
- pick_data.enabled = TRUE;
- LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data);
+ pick_panel->prepareNewPick(pos_global,
+ name,
+ mDescEditor->getText(),
+ mSnapshotCtrl->getImageAssetID(),
+ mParcelID);
}
// virtual
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 32ae4334aa..23a845bc20 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -38,15 +38,15 @@
#include "v3dmath.h"
#include "lluuid.h"
-#include "lliconctrl.h"
-
#include "llpanelmedia.h"
#include "llremoteparcelrequest.h"
class LLButton;
class LLInventoryItem;
class LLLineEditor;
+class LLPanelPick;
class LLParcel;
+class LLIconCtrl;
class LLTextBox;
class LLTextEditor;
class LLTextureCtrl;
@@ -88,7 +88,7 @@ public:
// Create a pick for the location specified
// by global_pos.
- void createPick(const LLVector3d& global_pos);
+ void createPick(const LLVector3d& pos_global, LLPanelPick* pick_panel);
BOOL isMediaPanelVisible();
void toggleMediaPanel(BOOL visible);
@@ -133,11 +133,13 @@ private:
LLUUID mParcelID;
LLUUID mRequestedID;
LLUUID mLandmarkID;
+ LLVector3 mPosRegion;
std::string mCurrentTitle;
S32 mMinHeight;
INFO_TYPE mInfoType;
LLTextBox* mTitle;
+ LLIconCtrl* mForSaleIcon;
LLTextureCtrl* mSnapshotCtrl;
LLTextBox* mRegionName;
LLTextBox* mParcelName;
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 11ddc3dd9a..80ecc95afb 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -48,14 +48,15 @@
#include "lluictrlfactory.h"
#include "llagent.h"
+#include "llavatarpropertiesprocessor.h"
#include "llfloaterworldmap.h"
#include "llinventorymodel.h"
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
#include "llpanelplaceinfo.h"
#include "llpanellandmarks.h"
+#include "llpanelpick.h"
#include "llpanelteleporthistory.h"
-#include "llsidetray.h"
#include "llteleporthistorystorage.h"
#include "lltoggleablemenu.h"
#include "llviewerinventory.h"
@@ -72,10 +73,12 @@ static const std::string REMOTE_PLACE_INFO_TYPE = "remote_place";
static const std::string TELEPORT_HISTORY_INFO_TYPE = "teleport_history";
// Helper functions
+static bool is_agent_in_selected_parcel(LLParcel* parcel);
static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
static std::string getFullFolderName(const LLViewerInventoryCategory* cat);
static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
static void onSLURLBuilt(std::string& slurl);
+static void setAllChildrenVisible(LLView* view, BOOL visible);
//Observer classes
class LLPlacesParcelObserver : public LLParcelObserver
@@ -118,6 +121,7 @@ LLPanelPlaces::LLPanelPlaces()
mActivePanel(NULL),
mFilterEditor(NULL),
mPlaceInfo(NULL),
+ mPickPanel(NULL),
mItem(NULL),
mPlaceMenu(NULL),
mLandmarkMenu(NULL),
@@ -332,7 +336,8 @@ void LLPanelPlaces::onFilterEdit(const std::string& search_string)
LLStringUtil::toUpper(mFilterSubString);
LLStringUtil::trimHead(mFilterSubString);
- mActivePanel->onSearchEdit(mFilterSubString);
+ if (mActivePanel)
+ mActivePanel->onSearchEdit(mFilterSubString);
}
}
@@ -380,7 +385,8 @@ void LLPanelPlaces::onTeleportButtonClicked()
}
else
{
- mActivePanel->onTeleport();
+ if (mActivePanel)
+ mActivePanel->onTeleport();
}
}
@@ -425,7 +431,8 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
}
else
{
- mActivePanel->onShowOnMap();
+ if (mActivePanel)
+ mActivePanel->onShowOnMap();
}
}
@@ -496,10 +503,23 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
{
if (!mPlaceInfo)
return;
-
- mPlaceInfo->createPick(mPosGlobal);
- onBackButtonClicked();
+ if (mPickPanel == NULL)
+ {
+ mPickPanel = new LLPanelPick();
+ addChild(mPickPanel);
+
+ mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
+ }
+
+ togglePickPanel(TRUE);
+
+ LLRect rect = getRect();
+ mPickPanel->reshape(rect.getWidth(), rect.getHeight());
+ mPickPanel->setRect(rect);
+ mPickPanel->setEditMode(TRUE);
+
+ mPlaceInfo->createPick(mPosGlobal, mPickPanel);
}
}
@@ -508,6 +528,12 @@ void LLPanelPlaces::onCreateLandmarkButtonClicked(const LLUUID& folder_id)
if (!mPlaceInfo)
return;
+ // To prevent creating duplicate landmarks
+ // disable landmark creating buttons until
+ // the information on existing landmarks is reloaded.
+ mCreateLandmarkBtn->setEnabled(FALSE);
+ mFolderMenuBtn->setEnabled(FALSE);
+
mPlaceInfo->createLandmark(folder_id);
}
@@ -544,6 +570,14 @@ void LLPanelPlaces::toggleMediaPanel()
onOpen(LLSD().insert("type", AGENT_INFO_TYPE));
}
+void LLPanelPlaces::togglePickPanel(BOOL visible)
+{
+ setAllChildrenVisible(this, !visible);
+
+ if (mPickPanel)
+ mPickPanel->setVisible(visible);
+}
+
void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
if (!mPlaceInfo)
@@ -568,16 +602,16 @@ void LLPanelPlaces::changedParcelSelection()
if (!mPlaceInfo)
return;
- mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
+ LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+ mParcel = parcel_mgr->getFloatingParcelSelection();
LLParcel* parcel = mParcel->getParcel();
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
+ LLViewerRegion* region = parcel_mgr->getSelectionRegion();
if (!region || !parcel)
return;
// If agent is inside the selected parcel show agent's region<X, Y, Z>,
// otherwise show region<X, Y, Z> of agent's selection point.
- if (region == gAgent.getRegion() &&
- parcel->getLocalID() == LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID())
+ if (is_agent_in_selected_parcel(parcel))
{
mPosGlobal = gAgent.getPositionGlobal();
}
@@ -629,6 +663,10 @@ void LLPanelPlaces::changedInventory(U32 mask)
mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel());
+ // Filter applied to show all items.
+ if (mActivePanel)
+ mActivePanel->onSearchEdit(mFilterSubString);
+
// we don't need to monitor inventory changes anymore,
// so remove the observer
gInventory.removeObserver(mInventoryObserver);
@@ -658,7 +696,7 @@ void LLPanelPlaces::updateVerbs()
bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE;
bool is_media_panel_visible = mPlaceInfo->isMediaPanelVisible();
-
+
mTeleportBtn->setVisible(!is_create_landmark_visible);
mShareBtn->setVisible(!is_create_landmark_visible);
mCreateLandmarkBtn->setVisible(is_create_landmark_visible);
@@ -679,10 +717,11 @@ void LLPanelPlaces::updateVerbs()
else if (is_create_landmark_visible)
{
// Enable "Create Landmark" only if there is no landmark
- // for the current parcel.
- bool no_landmark = !LLLandmarkActions::landmarkAlreadyExists();
- mCreateLandmarkBtn->setEnabled(no_landmark);
- mFolderMenuBtn->setEnabled(no_landmark);
+ // for the current parcel and agent is inside it.
+ bool enable = !LLLandmarkActions::landmarkAlreadyExists() &&
+ is_agent_in_selected_parcel(mParcel->getParcel());
+ mCreateLandmarkBtn->setEnabled(enable);
+ mFolderMenuBtn->setEnabled(enable);
}
else if (mPlaceInfoType == LANDMARK_INFO_TYPE || mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
{
@@ -693,7 +732,8 @@ void LLPanelPlaces::updateVerbs()
}
else
{
- mActivePanel->updateVerbs();
+ if (mActivePanel)
+ mActivePanel->updateVerbs();
}
}
@@ -822,6 +862,18 @@ void LLPanelPlaces::showLandmarkFoldersMenu()
LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop);
}
+static bool is_agent_in_selected_parcel(LLParcel* parcel)
+{
+ LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+
+ LLViewerRegion* region = parcel_mgr->getSelectionRegion();
+ if (!region || !parcel)
+ return false;
+
+ return region == gAgent.getRegion() &&
+ parcel->getLocalID() == parcel_mgr->getAgentParcel()->getLocalID();
+}
+
static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
{
return left.second < right.second;
@@ -895,3 +947,16 @@ static void onSLURLBuilt(std::string& slurl)
LLNotifications::instance().add("CopySLURL", args);
}
+
+static void setAllChildrenVisible(LLView* view, BOOL visible)
+{
+ const LLView::child_list_t* children = view->getChildList();
+ for (LLView::child_list_const_iter_t child_it = children->begin(); child_it != children->end(); ++child_it)
+ {
+ LLView* child = *child_it;
+ if (child->getParent() == view)
+ {
+ child->setVisible(visible);
+ }
+ }
+}
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 54bc2b9003..f208e91237 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -37,6 +37,7 @@
class LLInventoryItem;
class LLFilterEditor;
class LLLandmark;
+class LLPanelPick;
class LLPanelPlaceInfo;
class LLPanelPlacesTab;
class LLParcelSelection;
@@ -77,6 +78,7 @@ private:
void onBackButtonClicked();
void toggleMediaPanel();
+ void togglePickPanel(BOOL visible);
void togglePlaceInfoPanel(BOOL visible);
void onAgentParcelChange();
@@ -88,6 +90,7 @@ private:
LLPanelPlacesTab* mActivePanel;
LLTabContainer* mTabContainer;
LLPanelPlaceInfo* mPlaceInfo;
+ LLPanelPick* mPickPanel;
LLToggleableMenu* mPlaceMenu;
LLToggleableMenu* mLandmarkMenu;
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index ce01568e99..be28129451 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -104,10 +104,6 @@ void LLPanelProfile::onOpen(const LLSD& key)
{
getTabCtrl()->getCurrentPanel()->onOpen(getAvatarId());
}
-
- // Update the avatar name.
- gCacheName->get(getAvatarId(), FALSE,
- boost::bind(&LLPanelProfile::onAvatarNameCached, this, _1, _2, _3, _4));
}
//*TODO redo panel toggling
@@ -171,8 +167,3 @@ void LLPanelProfile::setAllChildrenVisible(BOOL visible)
}
}
-void LLPanelProfile::onAvatarNameCached(const LLUUID& id, const std::string& first_name, const std::string& last_name, BOOL is_group)
-{
- llassert(getAvatarId() == id);
- getChild<LLTextBox>("user_name", FALSE)->setValue(first_name + " " + last_name);
-}
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index 0864ec1bc3..bb893f257a 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -72,13 +72,6 @@ protected:
profile_tabs_t& getTabContainer() { return mTabContainer; }
private:
- // LLCacheName will call this function when avatar name is loaded from server.
- // This is required to display names that have not been cached yet.
- void onAvatarNameCached(
- const LLUUID& id,
- const std::string& first_name,
- const std::string& last_name,
- BOOL is_group);
LLTabContainer* mTabCtrl;
profile_tabs_t mTabContainer;
diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp
index 0762bbeb87..f1db2416e4 100644
--- a/indra/newview/llpanelprofileview.cpp
+++ b/indra/newview/llpanelprofileview.cpp
@@ -70,6 +70,10 @@ void LLPanelProfileView::onOpen(const LLSD& key)
setAvatarId(id);
}
+ // Update the avatar name.
+ gCacheName->get(getAvatarId(), FALSE,
+ boost::bind(&LLPanelProfileView::onAvatarNameCached, this, _1, _2, _3, _4));
+
// status should only show if viewer has permission to view online/offline. EXT-453
mStatusText->setVisible(isGrantedToSeeOnlineStatus());
updateOnlineStatus();
@@ -133,4 +137,21 @@ void LLPanelProfileView::updateOnlineStatus()
mStatusText->setValue(status);
}
+void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string& first_name, const std::string& last_name, BOOL is_group)
+{
+ llassert(getAvatarId() == id);
+ getChild<LLTextBox>("user_name", FALSE)->setValue(first_name + " " + last_name);
+}
+
+void LLPanelProfileView::togglePanel(LLPanel* panel)
+{
+ LLPanelProfile::togglePanel(panel);
+ if(FALSE == panel->getVisible())
+ {
+ // LLPanelProfile::togglePanel shows/hides all children,
+ // we don't want to display online status for non friends, so re-hide it here
+ mStatusText->setVisible(isGrantedToSeeOnlineStatus());
+ }
+}
+
// EOF
diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h
index 533ab94cc3..07a6c3a9a0 100644
--- a/indra/newview/llpanelprofileview.h
+++ b/indra/newview/llpanelprofileview.h
@@ -60,6 +60,8 @@ public:
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void togglePanel(LLPanel* panel);
+
protected:
void onBackBtnClick();
@@ -67,6 +69,14 @@ protected:
void updateOnlineStatus();
private:
+ // LLCacheName will call this function when avatar name is loaded from server.
+ // This is required to display names that have not been cached yet.
+ void onAvatarNameCached(
+ const LLUUID& id,
+ const std::string& first_name,
+ const std::string& last_name,
+ BOOL is_group);
+
LLTextBox* mStatusText;
};
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 1fd7928bfc..9754094aaa 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -40,6 +40,182 @@
#include "llteleporthistorystorage.h"
#include "llaccordionctrl.h"
#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, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name);
+ virtual ~LLTeleportHistoryFlatItem() {};
+
+ virtual BOOL postBuild();
+
+ S32 getIndex() { return mIndex; }
+
+ /*virtual*/ void setValue(const LLSD& value);
+
+ 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, 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");
+}
+
+//virtual
+BOOL LLTeleportHistoryFlatItem::postBuild()
+{
+ LLTextBox *region = getChild<LLTextBox>("region");
+ region->setValue(mRegionName);
+
+ mInfoBtn = getChild<LLButton>("info_btn");
+ mInfoBtn->setClickedCallback(boost::bind(&LLTeleportHistoryFlatItem::onInfoBtnClick, this));
+
+ return true;
+}
+
+void LLTeleportHistoryFlatItem::setValue(const LLSD& value)
+{
+ if (!value.isMap()) return;;
+ if (!value.has("selected")) return;
+ childSetVisible("selected_icon", value["selected"]);
+}
+
+void LLTeleportHistoryFlatItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ childSetVisible("hovered_icon", true);
+ mInfoBtn->setVisible(true);
+
+ LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLTeleportHistoryFlatItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ childSetVisible("hovered_icon", false);
+ mInfoBtn->setVisible(false);
+
+ LLPanel::onMouseLeave(x, y, mask);
+}
+
+// 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"] = 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");
@@ -48,7 +224,8 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()
: LLPanelPlacesTab(),
mFilterSubString(LLStringUtil::null),
mTeleportHistory(NULL),
- mHistoryAccordeon(NULL),
+ mHistoryAccordion(NULL),
+ mAccordionTabMenu(NULL),
mLastSelectedScrollList(NULL)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history.xml");
@@ -66,26 +243,27 @@ BOOL LLTeleportHistoryPanel::postBuild()
mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::showTeleportHistory, this));
}
- mHistoryAccordeon = getChild<LLAccordionCtrl>("history_accordion");
+ mHistoryAccordion = getChild<LLAccordionCtrl>("history_accordion");
- if (mHistoryAccordeon)
+ if (mHistoryAccordion)
{
- for (child_list_const_iter_t iter = mHistoryAccordeon->beginChild(); iter != mHistoryAccordeon->endChild(); iter++)
+ for (child_list_const_iter_t iter = mHistoryAccordion->beginChild(); iter != mHistoryAccordion->endChild(); iter++)
{
if (dynamic_cast<LLAccordionCtrlTab*>(*iter))
{
LLAccordionCtrlTab* tab = (LLAccordionCtrlTab*)*iter;
+ tab->setRightMouseDownCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionTabRightClick, this, _1, _2, _3, _4));
+
mItemContainers.put(tab);
- LLScrollListCtrl* sl = getScrollListFromTab(tab);
- if (sl)
+ LLFlatListView* fl = getFlatListViewFromTab(tab);
+ if (fl)
{
- sl->setDoubleClickCallback(onDoubleClickItem, this);
- sl->setCommitOnSelectionChange(FALSE);
- sl->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::handleItemSelect, this, sl));
+ fl->setCommitOnSelectionChange(true);
+ //fl->setDoubleClickCallback(onDoubleClickItem, this);
+ fl->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::handleItemSelect, this, fl));
}
-
}
}
}
@@ -109,13 +287,12 @@ void LLTeleportHistoryPanel::onShowOnMap()
if (!mLastSelectedScrollList)
return;
- LLScrollListItem* itemp = mLastSelectedScrollList->getFirstSelected();
+ LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem());
+
if(!itemp)
return;
- S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
-
- LLVector3d global_pos = mTeleportHistory->getItems()[mTeleportHistory->getItems().size() - 1 - index].mGlobalPos;
+ LLVector3d global_pos = mTeleportHistory->getItems()[itemp->getIndex()].mGlobalPos;
if (!global_pos.isExactlyZero())
{
@@ -130,14 +307,12 @@ void LLTeleportHistoryPanel::onTeleport()
if (!mLastSelectedScrollList)
return;
- LLScrollListItem* itemp = mLastSelectedScrollList->getFirstSelected();
+ LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem());
if(!itemp)
return;
- S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
-
// teleport to existing item in history, so we don't add it again
- mTeleportHistory->goToItem(mTeleportHistory->getItems().size() - 1 - index);
+ mTeleportHistory->goToItem(itemp->getIndex());
}
/*
@@ -177,15 +352,15 @@ void LLTeleportHistoryPanel::updateVerbs()
return;
}
- LLScrollListItem* itemp = mLastSelectedScrollList->getFirstSelected();
+ LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem());
- mTeleportBtn->setEnabled(NULL != itemp && 0 < itemp->getColumn(LIST_INDEX)->getValue().asInteger());
+ mTeleportBtn->setEnabled(NULL != itemp && 0 < itemp->getIndex());
mShowOnMapBtn->setEnabled(NULL != itemp);
}
void LLTeleportHistoryPanel::showTeleportHistory()
{
- if (!mHistoryAccordeon)
+ if (!mHistoryAccordion)
return;
const LLTeleportHistoryStorage::slurl_list_t& hist_items = mTeleportHistory->getItems();
@@ -193,15 +368,17 @@ void LLTeleportHistoryPanel::showTeleportHistory()
const U32 seconds_in_day = 24 * 60 * 60;
LLDate curr_date = LLDate::now();
- curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() + seconds_in_day);
-
S32 curr_tab = -1;
S32 tabs_cnt = mItemContainers.size();
S32 curr_year = 0, curr_month = 0, curr_day = 0;
+
+ curr_date.split(&curr_year, &curr_month, &curr_day);
+ curr_date.fromYMDHMS(curr_year, curr_month, curr_day); // Set hour, min, and sec to 0
+ curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() + seconds_in_day);
- LLScrollListCtrl *curr_scroll_list = NULL;
+ LLFlatListView* curr_flat_view = NULL;
- S32 index = 0;
+ S32 index = hist_items.size() - 1;
for (LLTeleportHistoryStorage::slurl_list_t::const_reverse_iterator iter = hist_items.rbegin();
iter != hist_items.rend(); ++iter)
@@ -219,71 +396,104 @@ void LLTeleportHistoryPanel::showTeleportHistory()
{
const LLDate &date = (*iter).mDate;
- S32 year, month, day;
- if (!date.split(&year, &month, &day))
- {
- llwarns << "Failed to split date: " << date << llendl;
- continue;
- }
-
- if (day != curr_day || month != curr_month || year != curr_year)
+ if (date < curr_date)
{
LLAccordionCtrlTab* tab = NULL;
- while (curr_tab < tabs_cnt - 1 && (day != curr_day || month != curr_month || year != curr_year))
+ while (curr_tab < tabs_cnt - 1 && date < curr_date)
{
curr_tab++;
tab = mItemContainers.get(mItemContainers.size() - 1 - curr_tab);
tab->setVisible(false);
-
- curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
- curr_date.split(&curr_year, &curr_month, &curr_day);
- }
+
+ if (curr_tab <= tabs_cnt - 4)
+ {
+ 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_month--;
+ if (0 == curr_month)
+ {
+ curr_month = 12;
+ curr_year--;
+ }
+ curr_date.fromYMDHMS(curr_year, curr_month, curr_day);
+ }
+ else if (curr_tab == tabs_cnt - 2) // 1 month and older, low boundary is 6 months
+ {
+ curr_date = LLDate::now();
+ curr_date.split(&curr_year, &curr_month, &curr_day);
+ if (curr_month > 6)
+ {
+ curr_month -= 6;
+ }
+ else
+ {
+ curr_month += 6;
+ curr_year--;
+ }
+ curr_date.fromYMDHMS(curr_year, curr_month, curr_day);
+
+ }
+ else // 6 months and older
+ {
+ curr_date.secondsSinceEpoch(0);
+ }
+ }
tab->setVisible(true);
- curr_scroll_list = getScrollListFromTab(tab);
- if (curr_scroll_list)
+ curr_flat_view = getFlatListViewFromTab(tab);
+ if (curr_flat_view)
{
- curr_scroll_list->deleteAllItems();
+ curr_flat_view->clear();
}
}
}
- LLSD row;
- row["id"] = index;
-
- if (curr_scroll_list)
- {
- LLSD& icon_column = row["columns"][LIST_ICON];
- icon_column["column"] = "landmark_icon";
- icon_column["type"] = "icon";
- icon_column["value"] = "inv_item_landmark.tga";
-
- LLSD& region_column = row["columns"][LIST_ITEM_TITLE];
- region_column["column"] = "region";
- region_column["type"] = "text";
- region_column["value"] = (*iter).mTitle;
-
- LLSD& index_column = row["columns"][LIST_INDEX];
- index_column["column"] = "index";
- index_column["type"] = "text";
- index_column["value"] = index;
-
- index++;
-
- curr_scroll_list->addElement(row);
+ if (curr_flat_view)
+ {
+ curr_flat_view->addItem(new LLTeleportHistoryFlatItem(index, &mContextMenu, (*iter).mTitle));
}
+
+ index--;
}
- mHistoryAccordeon->arrange();
+ // Hide empty tabs from current to bottom
+ for (curr_tab++; curr_tab < tabs_cnt; curr_tab++)
+ mItemContainers.get(mItemContainers.size() - 1 - curr_tab)->setVisible(false);
+
+ mHistoryAccordion->arrange();
updateVerbs();
}
-void LLTeleportHistoryPanel::handleItemSelect(LLScrollListCtrl* sl)
+void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
{
- mLastSelectedScrollList = sl;
+ mLastSelectedScrollList = selected;
+
+ S32 tabs_cnt = mItemContainers.size();
+
+ for (S32 n = 0; n < tabs_cnt; n++)
+ {
+ LLAccordionCtrlTab* tab = mItemContainers.get(n);
+
+ if (!tab->getVisible())
+ continue;
+
+ LLFlatListView *flv = getFlatListViewFromTab(tab);
+ if (!flv)
+ continue;
+
+ if (flv == selected)
+ continue;
+
+ flv->resetSelection(true);
+ }
+
updateVerbs();
}
@@ -303,15 +513,66 @@ void LLTeleportHistoryPanel::onDoubleClickItem(void* user_data)
LLSideTray::getInstance()->showPanel("panel_places", key);*/
}
-LLScrollListCtrl* LLTeleportHistoryPanel::getScrollListFromTab(LLAccordionCtrlTab *tab)
+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++)
{
- if (dynamic_cast<LLScrollListCtrl*>(*iter))
+ if (dynamic_cast<LLFlatListView*>(*iter))
{
- return (LLScrollListCtrl*)*iter; // There should be one scroll list per tab.
+ return (LLFlatListView*)*iter; // There should be one scroll list per tab.
}
}
return NULL;
}
+
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
index a1c15d087b..ebba25cfa5 100644
--- a/indra/newview/llpanelteleporthistory.h
+++ b/indra/newview/llpanelteleporthistory.h
@@ -34,18 +34,38 @@
#define LL_LLPANELTELEPORTHISTORY_H
#include "lluictrlfactory.h"
-#include "llscrolllistctrl.h"
#include "llpanelplacestab.h"
#include "llteleporthistory.h"
+#include "llmenugl.h"
class LLTeleportHistoryStorage;
class LLAccordionCtrl;
class LLAccordionCtrlTab;
+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,24 +79,23 @@ 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(LLScrollListCtrl* );
- LLScrollListCtrl* getScrollListFromTab(LLAccordionCtrlTab *);
-
- enum TELEPORT_HISTORY_COLUMN_ORDER
- {
- LIST_ICON,
- LIST_ITEM_TITLE,
- LIST_INDEX
- };
+ void handleItemSelect(LLFlatListView* );
+ LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *);
LLTeleportHistoryStorage* mTeleportHistory;
- LLAccordionCtrl* mHistoryAccordeon;
- LLScrollListCtrl* mLastSelectedScrollList;
+ LLAccordionCtrl* mHistoryAccordion;
+ LLFlatListView* mLastSelectedScrollList;
std::string mFilterSubString;
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/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
index 04abe36878..b491c7e109 100644
--- a/indra/newview/llrecentpeople.cpp
+++ b/indra/newview/llrecentpeople.cpp
@@ -40,27 +40,38 @@ using namespace LLOldEvents;
bool LLRecentPeople::add(const LLUUID& id)
{
- if (contains(id) || id == gAgent.getID())
+ if (id == gAgent.getID())
return false;
LLDate date_added = LLDate::now();
- mList.insert(std::make_pair(id, date_added));
+
+ //[] instead of insert to replace existing id->date with new date value
+ mPeople[id] = date_added;
mChangedSignal();
return true;
}
bool LLRecentPeople::contains(const LLUUID& id) const
{
- return mList.find(id) != mList.end();
+ return mPeople.find(id) != mPeople.end();
}
void LLRecentPeople::get(std::vector<LLUUID>& result) const
{
result.clear();
- for (recent_people_t::const_iterator pos = mList.begin(); pos != mList.end(); ++pos)
+ for (recent_people_t::const_iterator pos = mPeople.begin(); pos != mPeople.end(); ++pos)
result.push_back((*pos).first);
}
+const LLDate& LLRecentPeople::getDate(const LLUUID& id) const
+{
+ recent_people_t::const_iterator it = mPeople.find(id);
+ if (it!= mPeople.end()) return (*it).second;
+
+ static LLDate no_date = LLDate();
+ return no_date;
+}
+
// virtual
bool LLRecentPeople::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index c18116b4e5..e0f2faaec5 100644
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
@@ -81,6 +81,8 @@ public:
*/
void get(std::vector<LLUUID>& result) const;
+ const LLDate& getDate(const LLUUID& id) const;
+
/**
* Set callback to be called when the list changed.
*
@@ -97,7 +99,7 @@ public:
private:
typedef std::map<LLUUID, LLDate> recent_people_t;
- recent_people_t mList;
+ recent_people_t mPeople;
signal_t mChangedSignal;
};
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 1ac0175b83..95e3dd6d78 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -84,7 +84,7 @@ void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason
void LLRemoteParcelInfoProcessor::addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer)
{
- // Check if the observer is alredy in observsrs list for this UUID
+ // Check if the observer is already in observers list for this UUID
observer_multimap_t::iterator it;
it = mObservers.find(parcel_id);
@@ -155,7 +155,6 @@ void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, v
for (; oi != end; ++oi)
{
oi->second->processParcelInfo(parcel_data);
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_data.parcel_id, oi->second);
}
}
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 2157f1af74..8a96a5a1ae 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -39,9 +39,15 @@
#include "lltoastpanel.h"
#include "llviewercontrol.h"
+#include "llviewerwindow.h"
#include "llfloaterreg.h"
#include "lltrans.h"
+#include "lldockablefloater.h"
+#include "llimpanel.h"
+#include "llsyswellwindow.h"
+#include "llimfloater.h"
+
#include <algorithm>
using namespace LLNotificationsUI;
@@ -49,41 +55,86 @@ 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(false)
+//////////////////////
+// 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(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2));
+ setMouseOpaque( false );
+ setVisible(FALSE);
+}
+LLScreenChannelBase::~LLScreenChannelBase()
+{
+ mWorldViewRectConnection.disconnect();
+}
+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;
- setFollows(FOLLOWS_RIGHT | FOLLOWS_BOTTOM | FOLLOWS_TOP);
+ LLRect this_rect = getRect();
- mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString");
+ this_rect.mTop -= top_delta;
+ switch(mChannelAlignment)
+ {
+ case CA_LEFT :
+ break;
+ case CA_CENTRE :
+ this_rect.setCenterAndSize(new_world_rect.getWidth() / 2, new_world_rect.getHeight() / 2, this_rect.getWidth(), this_rect.getHeight());
+ break;
+ case CA_RIGHT :
+ this_rect.mLeft -= right_delta;
+ this_rect.mRight -= right_delta;
+ }
+ setRect(this_rect);
+ redrawToasts();
+
+}
- setMouseOpaque( false );
+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)
{
- S32 channel_top = getRootView()->getRect().getHeight() - gSavedSettings.getS32("NavBarMargin");
- S32 channel_bottom = getRootView()->getRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
- setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
-
+ LLScreenChannelBase::init(channel_left, channel_right);
}
//--------------------------------------------------------------------------
LLScreenChannel::~LLScreenChannel()
{
+
}
//--------------------------------------------------------------------------
-void LLScreenChannel::reshape(S32 width, S32 height, BOOL called_from_parent)
+void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
{
- LLUICtrl::reshape(width, height, called_from_parent);
- if(mToastAlignment != NA_CENTRE)
- showToasts();
+ LLScreenChannelBase::updatePositionAndSize(old_world_rect, new_world_rect);
}
//--------------------------------------------------------------------------
@@ -91,12 +142,12 @@ void LLScreenChannel::addToast(LLToast::Params p)
{
bool store_toast = false, show_toast = false;
- show_toast = 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)
{
- mOnRejectToast(p);
+ mRejectToastSignal(p.notif_id);
return;
}
@@ -104,7 +155,8 @@ void LLScreenChannel::addToast(LLToast::Params p)
mOverflowToastHidden = false;
- new_toast_elem.toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, new_toast_elem.toast));
+ new_toast_elem.toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, _1));
+ new_toast_elem.toast->setOnToastDestroyedCallback(boost::bind(&LLScreenChannel::onToastDestroyed, this, _1));
if(mControlHovering)
{
new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));
@@ -113,7 +165,7 @@ void LLScreenChannel::addToast(LLToast::Params p)
if(show_toast)
{
mToastList.push_back(new_toast_elem);
- showToasts();
+ redrawToasts();
}
else // store_toast
{
@@ -123,15 +175,27 @@ void LLScreenChannel::addToast(LLToast::Params p)
}
//--------------------------------------------------------------------------
+void LLScreenChannel::onToastDestroyed(LLToast* toast)
+{
+ std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), static_cast<LLPanel*>(toast));
+
+ if(it != mToastList.end())
+ {
+ mToastList.erase(it);
+ }
+}
+
+
+//--------------------------------------------------------------------------
void LLScreenChannel::onToastFade(LLToast* toast)
{
std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), static_cast<LLPanel*>(toast));
- bool destroy_toast = !mCanStoreToasts || !toast->getCanBeStored();
- if(destroy_toast)
+ bool delete_toast = !mCanStoreToasts || !toast->getCanBeStored();
+ if(delete_toast)
{
mToastList.erase(it);
- toast->mOnToastDestroy(toast);
+ deleteToast(toast);
}
else
{
@@ -139,7 +203,22 @@ void LLScreenChannel::onToastFade(LLToast* toast)
mToastList.erase(it);
}
- showToasts();
+ redrawToasts();
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::deleteToast(LLToast* toast)
+{
+ // send signal to observers about destroying of a toast
+ toast->mOnDeleteToastSignal(toast);
+
+ // update channel's Hovering state
+ // turning hovering off mannualy because onMouseLeave won't happen if a toast was closed using a keyboard
+ if(toast->hasFocus())
+ setHovering(false);
+
+ // close the toast
+ toast->closeFloater();
}
//--------------------------------------------------------------------------
@@ -173,11 +252,11 @@ void LLScreenChannel::loadStoredToastsToChannel()
}
mStoredToastList.clear();
- showToasts();
+ redrawToasts();
}
//--------------------------------------------------------------------------
-void LLScreenChannel::loadStoredToastByIDToChannel(LLUUID id)
+void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id)
{
std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
@@ -191,11 +270,11 @@ void LLScreenChannel::loadStoredToastByIDToChannel(LLUUID id)
mToastList.push_back((*it));
mStoredToastList.erase(it);
- showToasts();
+ redrawToasts();
}
//--------------------------------------------------------------------------
-void LLScreenChannel::removeStoredToastByID(LLUUID id)
+void LLScreenChannel::removeStoredToastByNotificationID(LLUUID id)
{
// *TODO: may be remove this function
std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
@@ -205,7 +284,7 @@ void LLScreenChannel::removeStoredToastByID(LLUUID id)
LLToast* toast = (*it).toast;
mStoredToastList.erase(it);
- toast->discardNotification();
+ mRejectToastSignal(toast->getNotificationID());
}
//--------------------------------------------------------------------------
@@ -223,15 +302,15 @@ void LLScreenChannel::killToastByNotificationID(LLUUID id)
// NOTE: if a notification is unresponded this function will be called twice for the same toast.
// At first, the notification will be discarded, at second (it will be caused by discarding),
// the toast will be destroyed.
- if(toast->getIsNotificationUnResponded())
+ if(toast->isNotificationValid())
{
- toast->discardNotification();
+ mRejectToastSignal(toast->getNotificationID());
}
else
{
mToastList.erase(it);
- toast->mOnToastDestroy(toast);
- showToasts();
+ deleteToast(toast);
+ redrawToasts();
}
return;
}
@@ -243,8 +322,9 @@ void LLScreenChannel::killToastByNotificationID(LLUUID id)
{
LLToast* toast = (*it).toast;
mStoredToastList.erase(it);
- toast->discardNotification();
- toast->mOnToastDestroy(toast);
+ // send signal to a listener to let him perform some action on toast rejecting
+ mRejectToastSignal(toast->getNotificationID());
+ deleteToast(toast);
}
}
@@ -261,12 +341,12 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)
delete old_panel;
toast->insertPanel(panel);
toast->resetTimer();
- showToasts();
+ redrawToasts();
}
}
//--------------------------------------------------------------------------
-void LLScreenChannel::showToasts()
+void LLScreenChannel::redrawToasts()
{
if(mToastList.size() == 0 || mIsHovering)
return;
@@ -487,31 +567,55 @@ void LLScreenChannel::removeToastsFromChannel()
hideToastsFromScreen();
for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++)
{
- // *TODO: ivestigate mOnToastDestroy callback - change name or/and place
- (*it).toast->mOnToastDestroy((*it).toast);
+ deleteToast((*it).toast);
}
mToastList.clear();
}
//--------------------------------------------------------------------------
-void LLScreenChannel::removeAndStoreAllVisibleToasts()
+void LLScreenChannel::removeAndStoreAllStorableToasts()
{
if(mToastList.size() == 0)
return;
hideToastsFromScreen();
- for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++)
+ for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end();)
{
if((*it).toast->getCanBeStored())
{
mStoredToastList.push_back(*it);
mOnStoreToast((*it).toast->getPanel(), (*it).id);
(*it).toast->stopTimer();
+ it = mToastList.erase(it);
+ }
+ else
+ {
+ ++it;
}
- (*it).toast->setVisible(FALSE);
}
+ redrawToasts();
+}
- mToastList.clear();
+//--------------------------------------------------------------------------
+void LLScreenChannel::removeToastsBySessionID(LLUUID id)
+{
+ if(mToastList.size() == 0)
+ return;
+
+ hideToastsFromScreen();
+ for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end();)
+ {
+ if((*it).toast->getSessionID() == id)
+ {
+ deleteToast((*it).toast);
+ it = mToastList.erase(it);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+ redrawToasts();
}
//--------------------------------------------------------------------------
@@ -546,11 +650,30 @@ void LLScreenChannel::onToastHover(LLToast* toast, bool mouse_enter)
}
if(!mIsHovering)
- showToasts();
+ redrawToasts();
}
//--------------------------------------------------------------------------
+void LLScreenChannel::updateShowToastsState()
+{
+ LLFloater* floater = LLDockableFloater::getInstanceHandle().get();
+ if(!floater)
+ {
+ setShowToasts(true);
+ return;
+ }
+ if(dynamic_cast<LLIMFloater*>(floater) || dynamic_cast<LLSysWellWindow*>(floater))
+ {
+ setShowToasts(!(floater->getVisible() && floater->isDocked()));
+ if (!getShowToasts())
+ {
+ removeAndStoreAllStorableToasts();
+ }
+
+ }
+}
+//--------------------------------------------------------------------------
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index 746580b574..459c28ac7c 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -48,11 +48,102 @@ typedef enum e_notification_toast_alignment
NA_BOTTOM,
} EToastAlignment;
+typedef enum e_channel_alignment
+{
+ CA_LEFT,
+ CA_CENTRE,
+ 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:
@@ -60,14 +151,10 @@ public:
virtual ~LLScreenChannel();
// Channel's outfit-functions
- // classic reshape
- void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ // update channel's size and position in the World View
+ 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(e_notification_toast_alignment align) {mToastAlignment = 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
@@ -80,61 +167,45 @@ public:
// removes all toasts from a channel
void removeToastsFromChannel();
// show all toasts in a channel
- void showToasts();
+ void redrawToasts();
//
void loadStoredToastsToChannel();
- // finds a toast among stored by its ID and throws it on a screen to a channel
- void loadStoredToastByIDToChannel(LLUUID id);
- // removes a toast from stored finding it by its ID
- void removeStoredToastByID(LLUUID id);
- // remove all toasts from screen and store them
- void removeAndStoreAllVisibleToasts();
+ // finds a toast among stored by its Notification ID and throws it on a screen to a channel
+ void loadStoredToastByNotificationIDToChannel(LLUUID id);
+ // removes a toast from stored finding it by its Notification ID
+ void removeStoredToastByNotificationID(LLUUID id);
+ // removes from channel all toasts that belongs to the certain IM session
+ void removeToastsBySessionID(LLUUID id);
+ // remove all storable toasts from screen and store them
+ void removeAndStoreAllStorableToasts();
// close the Overflow Toast
void closeOverflowToastPanel();
// 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 callbacks
- // callback for storing of faded toasts
+ // Channel's signals
+ // signal on storing of faded toasts event
typedef boost::function<void (LLPanel* info_panel, const LLUUID id)> store_tost_callback_t;
typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_tost_signal_t;
store_tost_signal_t mOnStoreToast;
boost::signals2::connection setOnStoreToastCallback(store_tost_callback_t cb) { return mOnStoreToast.connect(cb); }
- // callback for discarding of a rejected toast
- typedef boost::function<void (LLToast::Params p)> reject_tost_callback_t;
- typedef boost::signals2::signal<void (LLToast::Params p)> reject_tost_signal_t;
- reject_tost_signal_t mOnRejectToast;
- boost::signals2::connection setOnRejectToastCallback(reject_tost_callback_t cb) { return mOnRejectToast.connect(cb); }
+ // signal on rejecting of a toast event
+ typedef boost::function<void (LLUUID id)> reject_tost_callback_t;
+ typedef boost::signals2::signal<void (LLUUID id)> reject_tost_signal_t;
+ reject_tost_signal_t mRejectToastSignal;
+ boost::signals2::connection setOnRejectToastCallback(reject_tost_callback_t cb) { return mRejectToastSignal.connect(cb); }
private:
struct ToastElem
@@ -142,7 +213,7 @@ private:
LLUUID id;
LLToast* toast;
- ToastElem(LLToast::Params p) : id(p.id)
+ ToastElem(LLToast::Params p) : id(p.notif_id)
{
toast = new LLToast(p);
}
@@ -167,11 +238,14 @@ private:
// Channel's handlers
void onToastHover(LLToast* toast, bool mouse_enter);
void onToastFade(LLToast* toast);
+ void onToastDestroyed(LLToast* toast);
void onOverflowToastHide();
void onStartUpToastHide();
//
void storeToast(ToastElem& toast_elem);
+ // send signal to observers about destroying of a toast, update channel's Hovering state, close the toast
+ void deleteToast(LLToast* toast);
// show-functions depending on allignment of toasts
void showToastsBottom();
@@ -186,26 +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;
- //
- e_notification_toast_alignment mToastAlignment;
-
- // attributes for the Overflow Toast
- S32 mHiddenToastsNum;
- LLToast* mOverflowToastPanel;
- std::string mOverflowFormatString;
// attributes for the StartUp Toast
LLToast* mStartUpToastPanel;
- // channel's ID
- LLUUID mID;
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 d778d01bed..30ae9fcea1 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1127,6 +1127,17 @@ bool idle_startup()
// Don't pop up a notification in the TOS case because
// LLFloaterTOS::onCancel() already scolded the user.
if (reason_response != "tos")
+ // 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);
+ }
+
{
LLSD args;
args["ERROR_MESSAGE"] = emsg.str();
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 40b8445dcf..b0930cd86d 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -225,25 +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()
{
- mCommitCallbackRegistrar.add("HideNavbarMenu.Action", boost::bind(&LLStatusBar::onHideNavbarContextMenuItemClicked, this, _2));
- mEnableCallbackRegistrar.add("HideNavbarMenu.EnableMenuItem", boost::bind(&LLStatusBar::onHideNavbarContextMenuItemEnabled, this, _2));
-
- 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;
}
@@ -563,48 +552,6 @@ void LLStatusBar::setupDate()
}
}
-bool LLStatusBar::onHideNavbarContextMenuItemEnabled(const LLSD& userdata)
-{
- std::string item = userdata.asString();
-
- if (item == "show_navbar_navigation_panel")
- {
- return gSavedSettings.getBOOL("ShowNavbarNavigationPanel");
- }
- else if (item == "show_navbar_favorites_panel")
- {
- return gSavedSettings.getBOOL("ShowNavbarFavoritesPanel");
- }
-
- return FALSE;
-}
-
-void LLStatusBar::onHideNavbarContextMenuItemClicked(const LLSD& userdata)
-{
- std::string item = userdata.asString();
-
- if (item == "show_navbar_navigation_panel")
- {
- BOOL state = !gSavedSettings.getBOOL("ShowNavbarNavigationPanel");
-
- LLNavigationBar::getInstance()->showNavigationPanel(state);
- gSavedSettings.setBOOL("ShowNavbarNavigationPanel", state);
- }
- else if (item == "show_navbar_favorites_panel")
- {
- BOOL state = !gSavedSettings.getBOOL("ShowNavbarFavoritesPanel");
-
- LLNavigationBar::getInstance()->showFavoritesPanel(state);
- gSavedSettings.setBOOL("ShowNavbarFavoritesPanel", state);
- }
-}
-
-
-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 b77db2c525..d5629e6f1e 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -91,10 +91,6 @@ private:
// simple method to setup the part that holds the date
void setupDate();
- bool onHideNavbarContextMenuItemEnabled(const LLSD& userdata);
- void onHideNavbarContextMenuItemClicked(const LLSD& userdata);
-
- 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);
@@ -114,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/llsyswellitem.cpp b/indra/newview/llsyswellitem.cpp
index 7d9ebc7208..eef8435006 100644
--- a/indra/newview/llsyswellitem.cpp
+++ b/indra/newview/llsyswellitem.cpp
@@ -40,7 +40,7 @@
#include "lluicolortable.h"
//---------------------------------------------------------------------------------
-LLSysWellItem::LLSysWellItem(const Params& p) : LLScrollingPanel(p),
+LLSysWellItem::LLSysWellItem(const Params& p) : LLPanel(p),
mTitle(NULL),
mCloseBtn(NULL),
mIcon(NULL)
@@ -75,15 +75,6 @@ void LLSysWellItem::onClickCloseBtn()
}
//---------------------------------------------------------------------------------
-void LLSysWellItem::updatePanel(BOOL allow_modify)
-{
- S32 parent_width = getParent()->getRect().getWidth();
- S32 panel_height = getRect().getHeight();
-
- reshape(parent_width, panel_height, TRUE);
-}
-
-//---------------------------------------------------------------------------------
BOOL LLSysWellItem::handleMouseDown(S32 x, S32 y, MASK mask)
{
if(!mCloseBtn->getRect().pointInRect(x, y))
diff --git a/indra/newview/llsyswellitem.h b/indra/newview/llsyswellitem.h
index b0761f2790..b9b00e972a 100644
--- a/indra/newview/llsyswellitem.h
+++ b/indra/newview/llsyswellitem.h
@@ -33,14 +33,14 @@
#ifndef LL_LLSYSWELLITEM_H
#define LL_LLSYSWELLITEM_H
-#include "llscrollingpanellist.h"
+#include "llpanel.h"
#include "lltextbox.h"
#include "llbutton.h"
#include "lliconctrl.h"
#include <string>
-class LLSysWellItem : public LLScrollingPanel
+class LLSysWellItem : public LLPanel
{
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
@@ -54,8 +54,6 @@ public:
LLSysWellItem(const Params& p);
virtual ~LLSysWellItem();
- void updatePanel(BOOL allow_modify);
-
// title
void setTitle( std::string title );
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 98428bf0f7..669d8d1d70 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -32,6 +32,8 @@
#include "llviewerprecompiledheaders.h" // must be first include
+#include "llflatlistview.h"
+
#include "llsyswellwindow.h"
#include "llbottomtray.h"
@@ -39,89 +41,169 @@
#include "llviewerwindow.h"
#include "llchiclet.h"
+#include "lltoastpanel.h"
+#include "llnotificationmanager.h"
+
+
+// IM session ID can be the same as Avatar UUID. (See LLIMMgr::computeSessionID)
+// Probably notification ID also can be the same as Avatar UUID.
+// In case when session ID & notification ID are the same it will be impossible to add both
+// appropriate Items into Flat List.
+// Functions below are intended to wrap passed LLUUID into LLSD value with different "type".
+// Use them anywhere you need to add, get, remove items via the list
+inline
+LLSD get_notification_value(const LLUUID& notification_id)
+{
+ return LLSD()
+ .insert("type", "notification")
+ .insert("uuid", notification_id);
+}
+
+inline
+LLSD get_session_value(const LLUUID& session_id)
+{
+ return LLSD()
+ .insert("type", "im_chiclet")
+ .insert("uuid", session_id);
+}
+
+
//---------------------------------------------------------------------------------
LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLDockableFloater(NULL, key),
mChannel(NULL),
- mScrollContainer(NULL),
- mNotificationList(NULL)
+ mMessageList(NULL),
+ mSeparator(NULL)
{
LLIMMgr::getInstance()->addSessionObserver(this);
LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLSysWellWindow::findIMChiclet, this, _1));
+
+ mTypedItemsCount[IT_NOTIFICATION] = 0;
+ mTypedItemsCount[IT_INSTANT_MESSAGE] = 0;
}
//---------------------------------------------------------------------------------
BOOL LLSysWellWindow::postBuild()
{
- mScrollContainer = getChild<LLScrollContainer>("notification_list_container");
- mTwinListPanel = getChild<LLPanel>("twin_list_panel");
- mNotificationList = getChild<LLScrollingPanelList>("notification_list");
- mIMRowList = getChild<LLScrollingPanelList>("im_row_panel_list");
+ mMessageList = getChild<LLFlatListView>("notification_list");
+
+ // init connections to the list's update events
+ connectListUpdaterToSignal("notify");
+ connectListUpdaterToSignal("groupnotify");
+
+ // get a corresponding channel
+ initChannel();
- mScrollContainer->setBorderVisible(FALSE);
+ LLPanel::Params params;
+ mSeparator = LLUICtrlFactory::create<LLPanel>(params);
+ LLUICtrlFactory::instance().buildPanel(mSeparator, "panel_separator.xml");
+
+ LLRect rc = mSeparator->getRect();
+ rc.setOriginAndSize(0, 0, mMessageList->getItemsRect().getWidth(), rc.getHeight());
+ mSeparator->setRect(rc);
+ mSeparator->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP);
+ mSeparator->setVisible(FALSE);
+
+ mMessageList->addItem(mSeparator);
return LLDockableFloater::postBuild();
}
//---------------------------------------------------------------------------------
-LLSysWellWindow::~LLSysWellWindow()
+void LLSysWellWindow::setMinimized(BOOL minimize)
{
- LLIMMgr::getInstance()->removeSessionObserver(this);
+ // we don't show empty Message Well window
+ setVisible(!minimize && !isWindowEmpty());
+
+ LLFloater::setMinimized(minimize);
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::addItem(LLSysWellItem::Params p)
+void LLSysWellWindow::connectListUpdaterToSignal(std::string notification_type)
{
- // do not add clones
- if( findItemByID(p.notification_id) >= 0 )
- return;
+ LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
+ LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
+ if(n_handler)
+ {
+ n_handler->setNotificationIDCallback(boost::bind(&LLSysWellWindow::removeItemByID, this, _1));
+ }
+ else
+ {
+ llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl;
+ }
+}
- LLSysWellItem* new_item = new LLSysWellItem(p);
- mNotificationList->addPanel(dynamic_cast<LLScrollingPanel*>(new_item));
- reshapeWindow();
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::onChicletClick()
+{
+ // 1 - remove StartUp toast and channel if present
+ if(!LLNotificationsUI::LLScreenChannel::getStartUpToastShown())
+ {
+ LLNotificationsUI::LLChannelManager::getInstance()->onStartUpToastClose();
+ }
- new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
- new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
+ // 2 - toggle instance of SysWell's chiclet-window
+ toggleWindow();
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::clear()
+LLSysWellWindow::~LLSysWellWindow()
{
- // *TODO: fill later
+ LLIMMgr::getInstance()->removeSessionObserver(this);
}
//---------------------------------------------------------------------------------
-S32 LLSysWellWindow::findItemByID(const LLUUID& id)
+void LLSysWellWindow::addItem(LLSysWellItem::Params p)
{
- const LLScrollingPanelList::panel_list_t list = mNotificationList->getPanelList();
- if(list.size() == 0)
- return -1;
+ LLSD value = get_notification_value(p.notification_id);
+ // do not add clones
+ if( mMessageList->getItemByValue(value))
+ return;
- LLScrollingPanelList::panel_list_t::const_iterator it;
- S32 index = 0;
- for(it = list.begin(); it != list.end(); ++it, ++index)
+ LLSysWellItem* new_item = new LLSysWellItem(p);
+ if (mMessageList->addItem(new_item, value, ADD_TOP))
{
- if( dynamic_cast<LLSysWellItem*>(*it)->getID() == id )
- break;
- }
+ handleItemAdded(IT_NOTIFICATION);
+
+ reshapeWindow();
- if(it == list.end())
- return -1;
+ new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
+ new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
+ }
else
- return index;
+ {
+ llwarns << "Unable to add Notification into the list, notification ID: " << p.notification_id
+ << ", title: " << p.title
+ << llendl;
+ new_item->die();
+ }
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::removeItemByID(const LLUUID& id)
+void LLSysWellWindow::clear()
{
- S32 index = findItemByID(id);
+ mMessageList->clear();
+}
- if(index >= 0)
- mNotificationList->removePanel(index);
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::removeItemByID(const LLUUID& id)
+{
+ if(mMessageList->removeItemByValue(get_notification_value(id)))
+ {
+ handleItemRemoved(IT_NOTIFICATION);
+ reshapeWindow();
+ }
else
- return;
+ {
+ llwarns << "Unable to remove notification from the list, ID: " << id
+ << llendl;
+ }
- reshapeWindow();
+ // hide chiclet window if there are no items left
+ if(isWindowEmpty())
+ {
+ setVisible(FALSE);
+ }
}
//---------------------------------------------------------------------------------
@@ -129,7 +211,7 @@ void LLSysWellWindow::onItemClick(LLSysWellItem* item)
{
LLUUID id = item->getID();
if(mChannel)
- mChannel->loadStoredToastByIDToChannel(id);
+ mChannel->loadStoredToastByNotificationIDToChannel(id);
}
//---------------------------------------------------------------------------------
@@ -139,9 +221,37 @@ void LLSysWellWindow::onItemClose(LLSysWellItem* item)
removeItemByID(id);
if(mChannel)
mChannel->killToastByNotificationID(id);
+}
- // hide chiclet window if there are no items left
- setVisible(!isWindowEmpty());
+//--------------------------------------------------------------------------
+void LLSysWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
+{
+ LLSysWellItem::Params p;
+ p.notification_id = id;
+ p.title = static_cast<LLToastPanel*>(info_panel)->getTitle();
+ addItem(p);
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::initChannel()
+{
+ LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
+ LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+ mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
+ if(mChannel)
+ {
+ mChannel->setOnStoreToastCallback(boost::bind(&LLSysWellWindow::onStoreToast, this, _1, _2));
+ }
+ else
+ {
+ llwarns << "LLSysWellWindow::initChannel() - could not get a requested screen channel" << llendl;
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::getAllowedRect(LLRect& rect)
+{
+ rect = gViewerWindow->getWorldViewRect();
}
//---------------------------------------------------------------------------------
@@ -151,9 +261,26 @@ void LLSysWellWindow::toggleWindow()
{
setDockControl(new LLDockControl(
LLBottomTray::getInstance()->getSysWell(), this,
- getDockTongue(), LLDockControl::TOP, isDocked()));
+ getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getAllowedRect, this, _1)));
+ }
+
+ if(!getVisible())
+ {
+ if(mChannel)
+ {
+ mChannel->removeAndStoreAllStorableToasts();
+ }
+ if(isWindowEmpty())
+ {
+ return;
+ }
+
+ setVisible(TRUE);
+ }
+ else
+ {
+ setVisible(FALSE);
}
- setVisible(!getVisible());
//set window in foreground
setFocus(getVisible());
}
@@ -161,15 +288,12 @@ void LLSysWellWindow::toggleWindow()
//---------------------------------------------------------------------------------
void LLSysWellWindow::setVisible(BOOL visible)
{
- // on Show adjust position of SysWell chiclet's window
if(visible)
{
if (LLBottomTray::instanceExists())
{
LLBottomTray::getInstance()->getSysWell()->setToggleState(TRUE);
}
- if(mChannel)
- mChannel->removeAndStoreAllVisibleToasts();
}
else
{
@@ -178,86 +302,56 @@ void LLSysWellWindow::setVisible(BOOL visible)
LLBottomTray::getInstance()->getSysWell()->setToggleState(FALSE);
}
}
- if(mChannel)
- mChannel->setShowToasts(!visible);
LLDockableFloater::setVisible(visible);
+
+ // update notification channel state
+ if(mChannel)
+ {
+ mChannel->updateShowToastsState();
+ }
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::reshapeWindow()
+void LLSysWellWindow::setDocked(bool docked, bool pop_on_undock)
{
- // Get size for scrollbar and floater's header
- const LLUICachedControl<S32> SCROLLBAR_SIZE("UIScrollbarSize", 0);
- const LLUICachedControl<S32> HEADER_SIZE("UIFloaterHeaderSize", 0);
+ LLDockableFloater::setDocked(docked, pop_on_undock);
- LLRect notif_list_rect = mNotificationList->getRect();
- LLRect im_list_rect = mIMRowList->getRect();
- LLRect panel_rect = mTwinListPanel->getRect();
-
- S32 notif_list_height = notif_list_rect.getHeight();
- S32 im_list_height = im_list_rect.getHeight();
-
- S32 new_panel_height = notif_list_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + im_list_height;
- S32 new_window_height = new_panel_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + HEADER_SIZE;
-
- U32 twinListWidth = 0;
-
- if (new_window_height > MAX_WINDOW_HEIGHT)
- {
- twinListWidth = MIN_PANELLIST_WIDTH - SCROLLBAR_SIZE;
- new_window_height = MAX_WINDOW_HEIGHT;
- }
- else
+ // update notification channel state
+ if(mChannel)
{
- twinListWidth = MIN_PANELLIST_WIDTH;
+ mChannel->updateShowToastsState();
}
-
- reshape(MIN_WINDOW_WIDTH, new_window_height, FALSE);
- mTwinListPanel->reshape(twinListWidth, new_panel_height, TRUE);
- mNotificationList->reshape(twinListWidth, notif_list_height, TRUE);
- mIMRowList->reshape(twinListWidth, im_list_height, TRUE);
-
- // arrange panel and lists
- // move panel
- panel_rect.setLeftTopAndSize(1, new_panel_height, twinListWidth, new_panel_height);
- mTwinListPanel->setRect(panel_rect);
- // move notif list panel
- notif_list_rect.setLeftTopAndSize(notif_list_rect.mLeft, new_panel_height, twinListWidth, notif_list_height);
- mNotificationList->setRect(notif_list_rect);
- // move IM list panel
- im_list_rect.setLeftTopAndSize(im_list_rect.mLeft, notif_list_rect.mBottom - LLScrollingPanelList::GAP_BETWEEN_PANELS, twinListWidth, im_list_height);
- mIMRowList->setRect(im_list_rect);
-
- mNotificationList->updatePanels(TRUE);
- mIMRowList->updatePanels(TRUE);
}
//---------------------------------------------------------------------------------
-LLSysWellWindow::RowPanel * LLSysWellWindow::findIMRow(const LLUUID& sessionId)
+void LLSysWellWindow::reshapeWindow()
{
- RowPanel * res = NULL;
- const LLScrollingPanelList::panel_list_t &list = mIMRowList->getPanelList();
- if (!list.empty())
+ // save difference between floater height and the list height to take it into account while calculating new window height
+ // it includes height from floater top to list top and from floater bottom and list bottom
+ static S32 parent_list_delta_height = getRect().getHeight() - mMessageList->getRect().getHeight();
+
+ S32 notif_list_height = mMessageList->getItemsRect().getHeight() + 2 * mMessageList->getBorderWidth();
+
+ LLRect curRect = getRect();
+
+ S32 new_window_height = notif_list_height + parent_list_delta_height;
+
+ if (new_window_height > MAX_WINDOW_HEIGHT)
{
- for (LLScrollingPanelList::panel_list_t::const_iterator iter = list.begin(); iter != list.end(); ++iter)
- {
- RowPanel *panel = static_cast<RowPanel*> (*iter);
- if (panel->mChiclet->getSessionId() == sessionId)
- {
- res = panel;
- break;
- }
- }
+ new_window_height = MAX_WINDOW_HEIGHT;
}
- return res;
+ S32 newY = curRect.mTop + new_window_height - curRect.getHeight();
+ curRect.setLeftTopAndSize(curRect.mLeft, newY, MIN_WINDOW_WIDTH, new_window_height);
+ reshape(curRect.getWidth(), curRect.getHeight(), TRUE);
+ setRect(curRect);
}
//---------------------------------------------------------------------------------
LLChiclet* LLSysWellWindow::findIMChiclet(const LLUUID& sessionId)
{
LLChiclet* res = NULL;
- RowPanel* panel = findIMRow(sessionId);
+ RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(get_session_value(sessionId));
if (panel != NULL)
{
res = panel->mChiclet;
@@ -270,52 +364,67 @@ LLChiclet* LLSysWellWindow::findIMChiclet(const LLUUID& sessionId)
void LLSysWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,
const std::string& name, const LLUUID& otherParticipantId)
{
+ RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId);
+ if (mMessageList->insertItemAfter(mSeparator, item, get_session_value(sessionId)))
+ {
+ handleItemAdded(IT_INSTANT_MESSAGE);
+ }
+ else
+ {
+ llwarns << "Unable to add IM Row into the list, sessionID: " << sessionId
+ << ", name: " << name
+ << ", other participant ID: " << otherParticipantId
+ << llendl;
- mIMRowList->addPanel(new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId));
+ item->die();
+ }
}
//---------------------------------------------------------------------------------
void LLSysWellWindow::delIMRow(const LLUUID& sessionId)
{
- RowPanel *panel = findIMRow(sessionId);
- if (panel != NULL)
+ if (mMessageList->removeItemByValue(get_session_value(sessionId)))
+ {
+ handleItemRemoved(IT_INSTANT_MESSAGE);
+ }
+ else
{
- mIMRowList->removePanel(panel);
+ llwarns << "Unable to remove IM Row from the list, sessionID: " << sessionId
+ << llendl;
}
+ // remove all toasts that belong to this session from a screen
+ if(mChannel)
+ mChannel->removeToastsBySessionID(sessionId);
+
// hide chiclet window if there are no items left
- setVisible(!isWindowEmpty());
+ if(isWindowEmpty())
+ {
+ setVisible(FALSE);
+ }
}
//---------------------------------------------------------------------------------
bool LLSysWellWindow::isWindowEmpty()
{
- if(mIMRowList->getPanelList().size() == 0 && LLBottomTray::getInstance()->getSysWell()->getCounter() == 0)
- {
- return true;
- }
- else
- {
- return false;
- }
+ // keep in mind, mSeparator is always in the list
+ return mMessageList->size() == 1;
}
//---------------------------------------------------------------------------------
//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 (findIMRow(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();
}
}
@@ -328,10 +437,57 @@ void LLSysWellWindow::sessionRemoved(const LLUUID& sessionId)
LLBottomTray::getInstance()->getSysWell()->updateUreadIMNotifications();
}
+void LLSysWellWindow::handleItemAdded(EItemType added_item_type)
+{
+ bool should_be_shown = ++mTypedItemsCount[added_item_type] == 1 && anotherTypeExists(added_item_type);
+
+ if (should_be_shown && !mSeparator->getVisible())
+ {
+ mSeparator->setVisible(TRUE);
+
+ // refresh list to recalculate mSeparator position
+ mMessageList->reshape(mMessageList->getRect().getWidth(), mMessageList->getRect().getHeight());
+ }
+}
+
+void LLSysWellWindow::handleItemRemoved(EItemType removed_item_type)
+{
+ bool should_be_hidden = --mTypedItemsCount[removed_item_type] == 0;
+
+ if (should_be_hidden && mSeparator->getVisible())
+ {
+ mSeparator->setVisible(FALSE);
+
+ // refresh list to recalculate mSeparator position
+ mMessageList->reshape(mMessageList->getRect().getWidth(), mMessageList->getRect().getHeight());
+ }
+}
+
+bool LLSysWellWindow::anotherTypeExists(EItemType item_type)
+{
+ bool exists = false;
+ switch(item_type)
+ {
+ case IT_INSTANT_MESSAGE:
+ if (mTypedItemsCount[IT_NOTIFICATION] > 0)
+ {
+ exists = true;
+ }
+ break;
+ case IT_NOTIFICATION:
+ if (mTypedItemsCount[IT_INSTANT_MESSAGE] > 0)
+ {
+ exists = true;
+ }
+ break;
+ }
+ return exists;
+}
+
//---------------------------------------------------------------------------------
LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId,
S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) :
- LLScrollingPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent)
+ LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_activeim_row.xml", NULL);
@@ -342,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;
@@ -373,8 +530,8 @@ LLSysWellWindow::RowPanel::~RowPanel()
//---------------------------------------------------------------------------------
void LLSysWellWindow::RowPanel::onClose()
{
- mParent->mIMRowList->removePanel(this);
gIMMgr->removeSession(mChiclet->getSessionId());
+ // This row panel will be removed from the list in LLSysWellWindow::sessionRemoved().
}
//---------------------------------------------------------------------------------
@@ -400,13 +557,4 @@ BOOL LLSysWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask)
return LLPanel::handleMouseDown(x, y, mask);
}
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::RowPanel::updatePanel(BOOL allow_modify)
-{
- S32 parent_width = getParent()->getRect().getWidth();
- S32 panel_height = getRect().getHeight();
-
- reshape(parent_width, panel_height, TRUE);
-}
-
-//---------------------------------------------------------------------------------
+// EOF
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index d76147b489..203b949715 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -44,7 +44,7 @@
#include "boost/shared_ptr.hpp"
-
+class LLFlatListView;
class LLSysWellWindow : public LLDockableFloater, LLIMSessionObserver
{
@@ -54,36 +54,54 @@ public:
BOOL postBuild();
// other interface functions
+ // check is window empty
bool isWindowEmpty();
- // change attributes
- void setChannel(LLNotificationsUI::LLScreenChannel* channel) {mChannel = channel;}
-
// Operating with items
void addItem(LLSysWellItem::Params p);
void clear( void );
void removeItemByID(const LLUUID& id);
- S32 findItemByID(const LLUUID& id);
// Operating with outfit
virtual void setVisible(BOOL visible);
void adjustWindowPosition();
void toggleWindow();
- /*virtua*/BOOL canClose() { return FALSE; }
+ /*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);
void onItemClose(LLSysWellItem* item);
+ void onStoreToast(LLPanel* info_panel, LLUUID id);
+ void onChicletClick();
// size constants for the window and for its elements
static const S32 MAX_WINDOW_HEIGHT = 200;
- static const S32 MIN_WINDOW_WIDTH = 320;
- static const S32 MIN_PANELLIST_WIDTH = 318;
+ static const S32 MIN_WINDOW_WIDTH = 318;
private:
+
+ typedef enum{
+ IT_NOTIFICATION,
+ IT_INSTANT_MESSAGE
+ }EItemType;
+
+ // 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
+ void initChannel();
+ void handleItemAdded(EItemType added_item_type);
+ void handleItemRemoved(EItemType removed_item_type);
+ bool anotherTypeExists(EItemType item_type) ;
+
+
+
class RowPanel;
void reshapeWindow();
- RowPanel * findIMRow(const LLUUID& sessionId);
LLChiclet * findIMChiclet(const LLUUID& sessionId);
void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId);
void delIMRow(const LLUUID& sessionId);
@@ -93,23 +111,28 @@ private:
// pointer to a corresponding channel's instance
LLNotificationsUI::LLScreenChannel* mChannel;
- LLPanel* mTwinListPanel;
- LLScrollContainer* mScrollContainer;
- LLScrollingPanelList* mIMRowList;
- LLScrollingPanelList* mNotificationList;
+ LLFlatListView* mMessageList;
+
+ /**
+ * Special panel which is used as separator of Notifications & IM Rows.
+ * It is always presents in the list and shown when it is necessary.
+ * It should be taken into account when reshaping and checking list size
+ */
+ LLPanel* mSeparator;
+
+ typedef std::map<EItemType, S32> typed_items_count_t;
+ typed_items_count_t mTypedItemsCount;
private:
/**
* Scrolling row panel.
*/
- class RowPanel: public LLScrollingPanel
+ class RowPanel: public LLPanel
{
public:
RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, S32 chicletCounter,
const std::string& name, const LLUUID& otherParticipantId);
virtual ~RowPanel();
- /*virtual*/
- void updatePanel(BOOL allow_modify);
void onMouseEnter(S32 x, S32 y, MASK mask);
void onMouseLeave(S32 x, S32 y, MASK mask);
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index fb7574d68b..84931e4d2d 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -41,14 +41,14 @@
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),
- mID(p.id),
+ mNotificationID(p.notif_id),
+ mSessionID(p.session_id),
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)
@@ -66,19 +66,12 @@ LLToast::LLToast(LLToast::Params p) : LLFloater(LLSD()),
mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this));
}
- if(mIsModal)
- {
- gFocusMgr.setMouseCapture( this );
- gFocusMgr.setTopCtrl( this );
- setFocus(TRUE);
- }
-
-
- if(!p.on_toast_destroy.empty())
- mOnToastDestroy.connect(p.on_toast_destroy);
+ // init callbacks if present
+ if(!p.on_delete_toast.empty())
+ mOnDeleteToastSignal.connect(p.on_delete_toast);
if(!p.on_mouse_enter.empty())
- mOnMousEnter.connect(p.on_mouse_enter);
+ mOnMouseEnterSignal.connect(p.on_mouse_enter);
}
//--------------------------------------------------------------------------
@@ -102,11 +95,7 @@ void LLToast::setHideButtonEnabled(bool enabled)
//--------------------------------------------------------------------------
LLToast::~LLToast()
{
- if(mIsModal)
- {
- gFocusMgr.unlockFocus();
- gFocusMgr.releaseFocusIfNeeded( this );
- }
+ mOnToastDestroyedSignal(this);
}
//--------------------------------------------------------------------------
@@ -142,7 +131,7 @@ void LLToast::hide()
{
setVisible(FALSE);
mTimer.stop();
- mOnFade(this);
+ mOnFadeSignal(this);
}
//--------------------------------------------------------------------------
@@ -160,20 +149,35 @@ void LLToast::tick()
{
setVisible(FALSE);
mTimer.stop();
- mOnFade(this);
+ mOnFadeSignal(this);
}
}
//--------------------------------------------------------------------------
-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();
}
//--------------------------------------------------------------------------
@@ -188,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)
@@ -223,7 +215,7 @@ void LLToast::setVisible(BOOL show)
//--------------------------------------------------------------------------
void LLToast::onMouseEnter(S32 x, S32 y, MASK mask)
{
- mOnToastHover(this, MOUSE_ENTER);
+ mOnToastHoverSignal(this, MOUSE_ENTER);
setBackgroundOpaque(TRUE);
if(mCanFade)
@@ -234,13 +226,13 @@ void LLToast::onMouseEnter(S32 x, S32 y, MASK mask)
sendChildToFront(mHideBtn);
if(mHideBtn && mHideBtn->getEnabled())
mHideBtn->setVisible(TRUE);
- mOnMousEnter(this);
+ mOnMouseEnterSignal(this);
}
//--------------------------------------------------------------------------
void LLToast::onMouseLeave(S32 x, S32 y, MASK mask)
{
- mOnToastHover(this, MOUSE_LEAVE);
+ mOnToastHoverSignal(this, MOUSE_LEAVE);
if(mCanFade)
{
@@ -270,21 +262,11 @@ BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask)
}
//--------------------------------------------------------------------------
-void LLToast::discardNotification()
-{
- if(mNotification)
- {
- mNotification->setIgnored(TRUE);
- mNotification->respond(mNotification->getResponseTemplate());
- }
-}
-
-//--------------------------------------------------------------------------
-bool LLToast::getIsNotificationUnResponded()
+bool LLToast::isNotificationValid()
{
if(mNotification)
{
- return !mNotification->isRespondedTo();
+ return !mNotification->isCancelled();
}
return false;
}
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 05e63a60c5..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,19 +51,20 @@ 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;
typedef boost::signals2::signal<void (LLToast* toast)> toast_signal_t;
- struct Params : public LLInitParam::Block<Params, LLFloater::Params>
+ struct Params
{
LLPanel* panel;
- LLUUID id; //notification or message ID
+ LLUUID notif_id; //notification ID
+ LLUUID session_id; //im session ID
LLNotificationPtr notification;
F32 timer_period;
- toast_callback_t on_toast_destroy;
+ toast_callback_t on_delete_toast;
toast_callback_t on_mouse_enter;
bool can_fade;
bool can_be_stored;
@@ -98,10 +99,11 @@ public:
// Operating with toasts
// insert a panel to a toast
void insertPanel(LLPanel* panel);
+
+ void reshapeToPanel();
+
// get toast's panel
LLPanel* getPanel() { return mPanel; }
- // discard notification
- void discardNotification();
// enable/disable Toast's Hide button
void setHideButtonEnabled(bool enabled);
// initialize and start Toast's timer
@@ -120,30 +122,32 @@ public:
// get/set Toast's flags or states
- // get information whether the notification corresponding to the toast is responded or not
- bool getIsNotificationUnResponded();
+ // get information whether the notification corresponding to the toast is valid or not
+ bool isNotificationValid();
+ // get toast's Notification ID
+ const LLUUID getNotificationID() { return mNotificationID;}
+ // get toast's Session ID
+ const LLUUID getSessionID() { return mSessionID;}
//
void setCanFade(bool can_fade);
//
void setCanBeStored(bool can_be_stored) { mCanBeStored = can_be_stored; }
//
bool getCanBeStored() { return mCanBeStored; }
- //
- void setModal(bool modal);
- // Registers callbacks for events
- toast_signal_t mOnFade;
- toast_signal_t mOnMousEnter;
- toast_signal_t mOnToastDestroy;
- boost::signals2::connection setOnFadeCallback(toast_callback_t cb) { return mOnFade.connect(cb); }
- boost::signals2::connection setOnMouseEnterCallback(toast_callback_t cb) { return mOnMousEnter.connect(cb); }
- boost::signals2::connection setOnToastDestroyCallback(toast_callback_t cb) { return mOnToastDestroy.connect(cb); }
+ // Registers signals/callbacks for events
+ toast_signal_t mOnFadeSignal;
+ toast_signal_t mOnMouseEnterSignal;
+ toast_signal_t mOnDeleteToastSignal;
+ toast_signal_t mOnToastDestroyedSignal;
+ boost::signals2::connection setOnFadeCallback(toast_callback_t cb) { return mOnFadeSignal.connect(cb); }
+ boost::signals2::connection setOnToastDestroyedCallback(toast_callback_t cb) { return mOnToastDestroyedSignal.connect(cb); }
typedef boost::function<void (LLToast* toast, bool mouse_enter)> toast_hover_check_callback_t;
typedef boost::signals2::signal<void (LLToast* toast, bool mouse_enter)> toast_hover_check_signal_t;
- toast_hover_check_signal_t mOnToastHover;
- boost::signals2::connection setOnToastHoverCallback(toast_hover_check_callback_t cb) { return mOnToastHover.connect(cb); }
+ toast_hover_check_signal_t mOnToastHoverSignal;
+ boost::signals2::connection setOnToastHoverCallback(toast_hover_check_callback_t cb) { return mOnToastHoverSignal.connect(cb); }
private:
@@ -153,7 +157,8 @@ private:
// on timer finished function
void tick();
- LLUUID mID;
+ LLUUID mNotificationID;
+ LLUUID mSessionID;
LLNotificationPtr mNotification;
LLTimer mTimer;
@@ -164,7 +169,6 @@ private:
LLColor4 mBgColor;
bool mCanFade;
- bool mIsModal;
bool mCanBeStored;
bool mHideBtnEnabled;
bool mHideBtnPressed;
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index d401943020..fe1492d937 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -44,14 +44,14 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_instant_message.xml");
- mAvatar = getChild<LLAvatarIconCtrl>("avatar");
+ LLIconCtrl* sys_msg_icon = getChild<LLIconCtrl>("sys_msg_icon");
+ mAvatar = getChild<LLAvatarIconCtrl>("avatar_icon");
mUserName = getChild<LLTextBox>("user_name");
mTime = getChild<LLTextBox>("time_box");
mMessage = getChild<LLTextBox>("message");
mReplyBtn = getChild<LLButton>("reply");
mMessage->setValue(p.message);
- mAvatar->setValue(p.avatar_id);
mUserName->setValue(p.from);
mTime->setValue(p.time);
mSessionID = p.session_id;
@@ -60,6 +60,9 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
// if message comes from the system - there shouldn't be a reply btn
if(p.from == "Second Life")
{
+ mAvatar->setVisible(FALSE);
+ sys_msg_icon->setVisible(TRUE);
+
mReplyBtn->setVisible(FALSE);
S32 btn_height = mReplyBtn->getRect().getHeight();
LLRect msg_rect = mMessage->getRect();
@@ -68,6 +71,10 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
}
else
{
+ mAvatar->setVisible(TRUE);
+ sys_msg_icon->setVisible(FALSE);
+
+ mAvatar->setValue(p.avatar_id);
mReplyBtn->setClickedCallback(boost::bind(&LLToastIMPanel::onClickReplyBtn, this));
}
@@ -88,9 +95,7 @@ LLToastIMPanel::~LLToastIMPanel()
//--------------------------------------------------------------------------
void LLToastIMPanel::onClickReplyBtn()
{
- LLSD response = mNotification->getResponseTemplate();
- response["respondbutton"] = true;
- mNotification->respond(response);
+ mNotification->respond(mNotification->getResponseTemplate());
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index b51ce23364..af21b07a3d 100644
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -43,7 +43,7 @@
class LLToastIMPanel: public LLToastPanel
{
public:
- struct Params : public LLInitParam::Block<Params>
+ struct Params
{
LLNotificationPtr notification;
LLUUID avatar_id;
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 844c54da6a..9761a45d83 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -171,6 +171,7 @@ LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : LLToas
params.name("box");
params.rect(LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16));
params.max_text_length(MAX_LENGTH);
+ params.read_only(true);
params.default_text(mMessage);
params.font(sFont);
params.embedded_items(false);
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/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 08040cfaa5..c3064ffa43 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -54,6 +54,7 @@
#include "llmutelist.h"
#include "llnotify.h"
#include "llpreviewnotecard.h"
+#include "llrecentpeople.h"
#include "llselectmgr.h"
#include "lltoolmgr.h"
#include "lltooltip.h"
@@ -646,6 +647,7 @@ void LLToolDragAndDrop::beginMultiDrag(
void LLToolDragAndDrop::endDrag()
{
+ mEndDragSignal();
LLSelectMgr::getInstance()->unhighlightAll();
setMouseCapture(FALSE);
}
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index c9fef26b58..acf01869e7 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -51,6 +51,8 @@ class LLPickInfo;
class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop>
{
public:
+ typedef boost::signals2::signal<void ()> enddrag_signal_t;
+
LLToolDragAndDrop();
// overridden from LLTool
@@ -87,6 +89,8 @@ public:
const LLUUID& getObjectID() const { return mObjectID; }
EAcceptance getLastAccept() { return mLastAccept; }
+ boost::signals2::connection setEndDragCallback( const enddrag_signal_t::slot_type& cb ) { return mEndDragSignal.connect(cb); }
+
protected:
enum EDropTarget
{
@@ -131,6 +135,8 @@ protected:
S32 mCurItemIndex;
std::string mToolTipMsg;
+ enddrag_signal_t mEndDragSignal;
+
// array of pointers to functions that implement the logic to
// dragging and dropping into the simulator.
static dragOrDrop3dImpl sDragAndDrop3d[DAD_COUNT][DT_COUNT];
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/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index b888560fc7..24f4745c18 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -72,6 +72,8 @@
#include "llvosurfacepatch.h"
#include "llvowlsky.h"
#include "llrender.h"
+#include "llbottomtray.h"
+#include "llnavigationbar.h"
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
BOOL gHackGodmode = FALSE;
@@ -483,6 +485,36 @@ bool toggle_agent_pause(const LLSD& newvalue)
return true;
}
+bool toggle_show_gesture_button(const LLSD& newvalue)
+{
+ LLBottomTray::getInstance()->showGestureButton(newvalue.asBoolean());
+ return true;
+}
+
+bool toggle_show_move_button(const LLSD& newvalue)
+{
+ LLBottomTray::getInstance()->showMoveButton(newvalue.asBoolean());
+ return true;
+}
+
+bool toggle_show_camera_button(const LLSD& newvalue)
+{
+ LLBottomTray::getInstance()->showCameraButton(newvalue.asBoolean());
+ return true;
+}
+
+bool toggle_show_navigation_panel(const LLSD& newvalue)
+{
+ LLNavigationBar::getInstance()->showNavigationPanel(newvalue.asBoolean());
+ return true;
+}
+
+bool toggle_show_favorites_panel(const LLSD& newvalue)
+{
+ LLNavigationBar::getInstance()->showFavoritesPanel(newvalue.asBoolean());
+ return true;
+}
+
////////////////////////////////////////////////////////////////////////////
void settings_setup_listeners()
@@ -619,6 +651,11 @@ void settings_setup_listeners()
gSavedSettings.getControl("QAMode")->getSignal()->connect(boost::bind(&show_debug_menus));
gSavedSettings.getControl("UseDebugMenus")->getSignal()->connect(boost::bind(&show_debug_menus));
gSavedSettings.getControl("AgentPause")->getSignal()->connect(boost::bind(&toggle_agent_pause, _2));
+ gSavedSettings.getControl("ShowGestureButton")->getSignal()->connect(boost::bind(&toggle_show_gesture_button, _2));
+ gSavedSettings.getControl("ShowMoveButton")->getSignal()->connect(boost::bind(&toggle_show_move_button, _2));
+ gSavedSettings.getControl("ShowCameraButton")->getSignal()->connect(boost::bind(&toggle_show_camera_button, _2));
+ gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2));
+ gSavedSettings.getControl("ShowNavbarFavoritesPanel")->getSignal()->connect(boost::bind(&toggle_show_favorites_panel, _2));
}
#if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 441d0ebeaa..2f656479f6 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -65,10 +65,12 @@
#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"
#include "llimpanel.h"
#include "llfloaterinspect.h"
#include "llfloaterinventory.h"
@@ -104,6 +106,7 @@
#include "llfloaterurldisplay.h"
#include "llfloatervoicedevicesettings.h"
#include "llfloaterwater.h"
+#include "llfloaterwhitelistentry.h"
#include "llfloaterwindlight.h"
#include "llfloaterworldmap.h"
#include "llinspectavatar.h"
@@ -143,6 +146,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
+ LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
LLFloaterReg::add("chat", "floater_chat_history.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChat>);
LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
LLFloaterReg::add("communicate", "floater_chatterbox.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatterBox>);
@@ -162,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>);
@@ -176,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>);
@@ -236,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 5289037c7a..1ec94b5bd2 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;
}
@@ -811,49 +1149,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;
@@ -882,6 +1198,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
@@ -935,12 +1255,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();
@@ -965,9 +1284,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;
@@ -1001,11 +1317,6 @@ void LLViewerMediaImpl::setVisible(bool visible)
createMediaSource();
}
}
-
- if(mMediaSource)
- {
- mMediaSource->setPriority(mVisible?LLPluginClassMedia::PRIORITY_NORMAL:LLPluginClassMedia::PRIORITY_HIDDEN);
- }
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -1064,7 +1375,7 @@ bool LLViewerMediaImpl::hasMedia()
}
//////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event)
+void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent event)
{
switch(event)
{
@@ -1075,11 +1386,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);
}
////////////////////////////////////////////////////////////////////////////////
@@ -1142,6 +1519,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 53cf44214e..7dcc734816 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()
@@ -376,7 +374,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*);
@@ -1250,21 +1247,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 //
/////////////////////
@@ -3833,6 +3815,7 @@ void handle_reset_view()
}
else
{
+ gAgent.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
reset_view_final( TRUE );
LLFloaterCamera::resetCameraMode();
}
@@ -5589,11 +5572,6 @@ class LLObjectEnableSitOrStand : public view_listener_t
}
};
-void edit_ui(void*)
-{
- LLFloater::setEditModeEnabled(!LLFloater::getEditModeEnabled());
-}
-
void dump_select_mgr(void*)
{
LLSelectMgr::getInstance()->dump();
@@ -5651,8 +5629,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")
{
@@ -7691,6 +7669,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.
@@ -7888,7 +7879,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/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a2277e4406..5e000bba6d 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -98,6 +98,7 @@
#include "llnotifications.h"
#include "llnotify.h"
#include "llpanelgrouplandmoney.h"
+#include "llrecentpeople.h"
#include "llselectmgr.h"
#include "llsidetray.h"
#include "llstartup.h"
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 a1db48529e..44de848d19 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 ae94fc6649..6af97e4b4c 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1565,9 +1565,19 @@ void LLViewerWindow::initWorldUI()
navbar->showFavoritesPanel(FALSE);
}
- if (!gSavedSettings.getBOOL("ShowCameraAndMoveControls"))
+ if (!gSavedSettings.getBOOL("ShowCameraButton"))
{
- LLBottomTray::getInstance()->showCameraAndMoveControls(FALSE);
+ LLBottomTray::getInstance()->showCameraButton(FALSE);
+ }
+
+ if (!gSavedSettings.getBOOL("ShowMoveButton"))
+ {
+ LLBottomTray::getInstance()->showMoveButton(FALSE);
+ }
+
+ if (!gSavedSettings.getBOOL("ShowGestureButton"))
+ {
+ LLBottomTray::getInstance()->showGestureButton(FALSE);
}
getRootView()->addChild(gStatusBar);
@@ -1583,13 +1593,6 @@ void LLViewerWindow::initWorldUI()
// menu holder appears on top to get first pass at all mouse events
getRootView()->sendChildToFront(gMenuHolder);
- //Channel Manager
- LLNotificationsUI::LLChannelManager* channel_manager = LLNotificationsUI::LLChannelManager::getInstance();
- getRootView()->addChild(channel_manager);
- //Notification Manager
- LLNotificationsUI::LLNotificationManager* notify_manager = LLNotificationsUI::LLNotificationManager::getInstance();
- getRootView()->addChild(notify_manager);
-
if ( gHUDView == NULL )
{
LLRect hud_rect = full_window;
@@ -2865,6 +2868,9 @@ void LLViewerWindow::updateWorldViewRect(bool use_full_window)
if (mWorldViewRect != new_world_rect)
{
+ // sending a signal with a new WorldView rect
+ mOnWorldViewRectUpdated(mWorldViewRect, new_world_rect);
+
mWorldViewRect = new_world_rect;
gResizeScreenTexture = TRUE;
LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRect.getHeight() );
@@ -3221,9 +3227,18 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans
pickAsync(x, y_from_bot, gKeyboard->currentMask(TRUE), NULL, pick_transparent);
// assume that pickAsync put the results in the back of the mPicks list
- mLastPick = mPicks.back();
- mLastPick.fetchResults();
- mPicks.pop_back();
+ if(mPicks.size() != 0)
+ {
+ mLastPick = mPicks.back();
+ mLastPick.fetchResults();
+ mPicks.pop_back();
+ }
+ else
+ {
+ llwarns << "List of last picks is empty" << llendl;
+ llwarns << "Using stub pick" << llendl;
+ mLastPick = LLPickInfo();
+ }
return mLastPick;
}
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 5d54cf1b7f..d7c403739e 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -199,6 +199,11 @@ public:
typedef boost::signals2::signal<void (void)> bottom_tray_signal_t;
bottom_tray_signal_t mOnBottomTrayWidthChanged;
boost::signals2::connection setOnBottomTrayWidthChanged(bottom_tray_callback_t cb) { return mOnBottomTrayWidthChanged.connect(cb); }
+ // signal on update of WorldView rect
+ typedef boost::function<void (LLRect old_world_rect, LLRect new_world_rect)> world_rect_callback_t;
+ typedef boost::signals2::signal<void (LLRect old_world_rect, LLRect new_world_rect)> world_rect_signal_t;
+ world_rect_signal_t mOnWorldViewRectUpdated;
+ boost::signals2::connection setOnWorldViewRectUpdated(world_rect_callback_t cb) { return mOnWorldViewRectUpdated.connect(cb); }
//
// ACCESSORS
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 746dc99e35..3c1ac3d571 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -46,6 +46,7 @@
# include "expat/expat.h"
#endif
#include "llcallbacklist.h"
+#include "llcallingcard.h" // for LLFriendObserver
#include "llviewerregion.h"
#include "llviewernetwork.h" // for gGridChoice
#include "llbase64.h"
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index fe99e787da..bddd18dee8 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -42,9 +42,9 @@ class LLVivoxProtocolParser;
#include "v3math.h"
#include "llframetimer.h"
#include "llviewerregion.h"
-#include "llcallingcard.h" // for LLFriendObserver
#include "m3math.h" // LLMatrix3
+class LLFriendObserver;
class LLVoiceClientParticipantObserver
{
public:
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/icons/Generic_Group.png b/indra/newview/skins/default/textures/icons/Generic_Group.png
index 909334d862..fdd65b49e1 100644
--- a/indra/newview/skins/default/textures/icons/Generic_Group.png
+++ b/indra/newview/skins/default/textures/icons/Generic_Group.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Generic_Person.png b/indra/newview/skins/default/textures/icons/Generic_Person.png
index 01618ce2c0..45b491ab59 100644
--- a/indra/newview/skins/default/textures/icons/Generic_Person.png
+++ b/indra/newview/skins/default/textures/icons/Generic_Person.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 8440022844..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" />
@@ -514,6 +509,9 @@
<texture name="toolbar_btn_disabled.tga" scale.left="7" scale.top="32" scale.right="121" scale.bottom="0" />
<texture name="toolbar_btn_selected.tga" scale.left="7" scale.top="32" scale.right="121" scale.bottom="0" />
+ <texture name="toggle_button_off" file_name="toggle_button_off.png" preload="true" />
+ <texture name="toggle_button_selected" file_name="toggle_button_selected.png" preload="true" />
+
<!--TODO: REPLACE CODE REFERENCE TO THIS ART WITH Icon_Minimize_Background above -->
<texture name="minimize_inactive.tga" preload="true" />
<texture name="minimize.tga" preload="true" />
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/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml
index 6b52da04d0..81d4d3fdfd 100644
--- a/indra/newview/skins/default/xui/da/floater_about.xml
+++ b/indra/newview/skins/default/xui/da/floater_about.xml
@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="floater_about" title="Om [APP_NAME]">
+<tab_container name="about_tab">
+ <panel name="credits_panel">
<text_editor name="credits_editor">
Second Life er gjort muligt for dig af Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl and many others.
Tak til følgende beboerne for at bidrage til at sikre, at dette er den bedste version til dato: able whitman, Adeon Writer, adonaira aabye, Aeron Kohime, Agathos Frascati, Aimee Trescothick, Aleric Inglewood, Alissa Sabre, Aminom Marvin, Angela Talamasca, Aralara Rajal, Armin Weatherwax, Ashrilyn Hayashida, Athanasius Skytower, Aura Dirval, Barney Boomslang, Biancaluce Robbiani, Biker Offcourse, Borg Capalini, Bulli Schumann, catherine pfeffer, Chalice Yao, Corre Porta, Court Goodman, Cummere Mayo, Dale Innis, Darien Caldwell, Darjeeling Schoonhoven, Daten Thielt, dimentox travanti, Dirk Talamasca, Drew Dwi, Duckless Vandyke, Elanthius Flagstaff, Electro Burnstein, emiley tomsen, Escort DeFarge, Eva Rau, Ezian Ecksol, Fire Centaur, Fluf Fredriksson, Francisco Koolhoven, Frontera Thor, Frungi Stastny, Gally Young, gearsawe stonecutter, Gigs Taggart, Gordon Wendt, Gudmund Shepherd, Gypsy Paz, Harleen Gretzky, Henri Beauchamp, Inma Rau, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Jessicka Graves, Joeseph Albanese, Joshua Philgarlic, Khyota Wulluf, kirstenlee Cinquetti, Latif Khalifa, Lex Neva, Lilibeth Andree, Lisa Lowe, Lunita Savira, Loosey Demonia, lum pfohl, Marcos Fonzarelli, MartinRJ Fayray, Marusame Arai, Matthew Dowd, Maya Remblai, McCabe Maxsted, Meghan Dench, Melchoir Tokhes, Menos Short, Michelle2 Zenovka, Mimika Oh, Minerva Memel, Mm Alder, Ochi Wolfe, Omei Turnbull, Pesho Replacement, Phantom Ninetails, phoenixflames kukulcan, Polo Gufler, prez pessoa, princess niven, Prokofy Neva, Qie Niangao, Rem Beattie, RodneyLee Jessop, Saijanai Kuhn, Seg Baphomet, Sergen Davies, Shirley Marquez, SignpostMarv Martin, Sindy Tsure, Sira Arbizu, Skips Jigsaw, Sougent Harrop, Spritely Pixel, Squirrel Wood, StarSong Bright, Subversive Writer, Sugarcult Dagger, Sylumm Grigorovich, Tammy Nowotny, Tanooki Darkes, Tayra Dagostino, Theoretical Chemistry, Thickbrick Sleaford, valerie rosewood, Vex Streeter, Vixen Heron, Whoops Babii, Winter Ventura, Xiki Luik, Yann Dufaux, Yina Yao, Yukinoroh Kamachi, Zolute Infinity, Zwagoth Klaar
+
+
+I get by with a little help from my friends. --Richard Starkey
+ </text_editor>
+ </panel>
+ <panel name="licenses_panel">
+ <text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
APR Copyright (C) 2000-2004 The Apache Software Foundation
cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
@@ -26,10 +35,9 @@ Tak til følgende beboerne for at bidrage til at sikre, at dette er den bedste v
Alle rettigheder forbeholdes. Se licenses.txt for detaljer.
Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
-
-
-I get by with a little help from my friends. --Richard Starkey
</text_editor>
+ </panel>
+</tab_container>
<string name="you_are_at">
Du er ved [POSITION]
</string>
diff --git a/indra/newview/skins/default/xui/da/floater_map.xml b/indra/newview/skins/default/xui/da/floater_map.xml
index b30205310a..f618548908 100644
--- a/indra/newview/skins/default/xui/da/floater_map.xml
+++ b/indra/newview/skins/default/xui/da/floater_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Map">
- <floater.string name="mini_map_north">
- N
- </floater.string>
- <floater.string name="mini_map_east">
- Ø
- </floater.string>
- <floater.string name="mini_map_west">
- V
- </floater.string>
- <floater.string name="mini_map_south">
- S
- </floater.string>
- <floater.string name="mini_map_southeast">
- SØ
- </floater.string>
- <floater.string name="mini_map_northeast">
- NØ
- </floater.string>
- <floater.string name="mini_map_southwest">
- SV
- </floater.string>
- <floater.string name="mini_map_northwest">
- NV
- </floater.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="Ø" name="floater_map_east" text="Ø">
- Ø
- </text>
- <text label="V" name="floater_map_west" text="V">
- V
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SØ" name="floater_map_southeast" text="SØ">
- SØ
- </text>
- <text label="NØ" name="floater_map_northeast" text="NØ">
- NØ
- </text>
- <text label="SV" name="floater_map_southwest" text="SV">
- SV
- </text>
- <text label="NV" name="floater_map_northwest" text="NV">
- NV
- </text>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Map">
+ <floater.string name="mini_map_north">
+ N
+ </floater.string>
+ <floater.string name="mini_map_east">
+ Ø
+ </floater.string>
+ <floater.string name="mini_map_west">
+ V
+ </floater.string>
+ <floater.string name="mini_map_south">
+ S
+ </floater.string>
+ <floater.string name="mini_map_southeast">
+ SØ
+ </floater.string>
+ <floater.string name="mini_map_northeast">
+ NØ
+ </floater.string>
+ <floater.string name="mini_map_southwest">
+ SV
+ </floater.string>
+ <floater.string name="mini_map_northwest">
+ NV
+ </floater.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="Ø" name="floater_map_east" text="Ø">
+ Ø
+ </text>
+ <text label="V" name="floater_map_west" text="V">
+ V
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SØ" name="floater_map_southeast" text="SØ">
+ SØ
+ </text>
+ <text label="NØ" name="floater_map_northeast" text="NØ">
+ NØ
+ </text>
+ <text label="SV" name="floater_map_southwest" text="SV">
+ SV
+ </text>
+ <text label="NV" name="floater_map_northwest" text="NV">
+ NV
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml
index 61f27d5543..d3d017914d 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="advanced">
- <text name="AspectRatioLabel1" tool_tip="bredde / højde">
- Format:
- </text>
- <combo_box name="aspect_ratio" tool_tip="bredde/ højde">
- <combo_box.item label="4:3 (Standard CRT)" name="item1"/>
- <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
- <combo_box.item label="8:5 (Widescreen)" name="item3"/>
- <combo_box.item label="16:9 (Widescreen)" name="item4"/>
- </combo_box>
-</panel>
+<?xml version="1.0" encoding="utf-8"?>
+<panel name="advanced">
+ <text name="AspectRatioLabel1" tool_tip="bredde / højde">
+ Format:
+ </text>
+ <combo_box name="aspect_ratio" tool_tip="bredde/ højde">
+ <combo_box.item label="4:3 (Standard CRT)" name="item1"/>
+ <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
+ <combo_box.item label="8:5 (Widescreen)" name="item3"/>
+ <combo_box.item label="16:9 (Widescreen)" name="item4"/>
+ </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_world_map.xml b/indra/newview/skins/default/xui/da/panel_world_map.xml
index b835180a88..d2ae3ab116 100644
--- a/indra/newview/skins/default/xui/da/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/da/panel_world_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="world_map">
- <panel.string name="world_map_north">
- N
- </panel.string>
- <panel.string name="world_map_east">
- Ø
- </panel.string>
- <panel.string name="world_map_west">
- V
- </panel.string>
- <panel.string name="world_map_south">
- S
- </panel.string>
- <panel.string name="world_map_southeast">
- SØ
- </panel.string>
- <panel.string name="world_map_northeast">
- NØ
- </panel.string>
- <panel.string name="world_map_southwest">
- SV
- </panel.string>
- <panel.string name="world_map_northwest">
- NV
- </panel.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="Ø" name="floater_map_east" text="Ø">
- Ø
- </text>
- <text label="V" name="floater_map_west" text="V">
- V
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SØ" name="floater_map_southeast" text="SØ">
- SØ
- </text>
- <text label="NØ" name="floater_map_northeast" text="NØ">
- NØ
- </text>
- <text label="SV" name="floater_map_southwest" text="SV">
- SV
- </text>
- <text label="NV" name="floater_map_northwest" text="NV">
- NV
- </text>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="world_map">
+ <panel.string name="world_map_north">
+ N
+ </panel.string>
+ <panel.string name="world_map_east">
+ Ø
+ </panel.string>
+ <panel.string name="world_map_west">
+ V
+ </panel.string>
+ <panel.string name="world_map_south">
+ S
+ </panel.string>
+ <panel.string name="world_map_southeast">
+ SØ
+ </panel.string>
+ <panel.string name="world_map_northeast">
+ NØ
+ </panel.string>
+ <panel.string name="world_map_southwest">
+ SV
+ </panel.string>
+ <panel.string name="world_map_northwest">
+ NV
+ </panel.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="Ø" name="floater_map_east" text="Ø">
+ Ø
+ </text>
+ <text label="V" name="floater_map_west" text="V">
+ V
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SØ" name="floater_map_southeast" text="SØ">
+ SØ
+ </text>
+ <text label="NØ" name="floater_map_northeast" text="NØ">
+ NØ
+ </text>
+ <text label="SV" name="floater_map_southwest" text="SV">
+ SV
+ </text>
+ <text label="NV" name="floater_map_northwest" text="NV">
+ NV
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml
index 340b90d802..d36f5a43f6 100644
--- a/indra/newview/skins/default/xui/de/floater_about.xml
+++ b/indra/newview/skins/default/xui/de/floater_about.xml
@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="floater_about" title="Über [APP_NAME]">
+<tab_container name="about_tab">
+ <panel name="credits_panel">
<text_editor name="credits_editor">
Second Life wird Ihnen präsentiert von Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl und vielen anderen.
Vielen Dank den folgenden Einwohnern, die uns geholfen haben, dies zur bisher besten Version zu machen: able whitman, Adeon Writer, adonaira aabye, Aeron Kohime, Agathos Frascati, Aimee Trescothick, Aleric Inglewood, Alissa Sabre, Aminom Marvin, Angela Talamasca, Aralara Rajal, Armin Weatherwax, Ashrilyn Hayashida, Athanasius Skytower, Aura Dirval, Barney Boomslang, Biancaluce Robbiani, Biker Offcourse, Borg Capalini, Bulli Schumann, catherine pfeffer, Chalice Yao, Corre Porta, Court Goodman, Cummere Mayo, Dale Innis, Darien Caldwell, Darjeeling Schoonhoven, Daten Thielt, dimentox travanti, Dirk Talamasca, Drew Dwi, Duckless Vandyke, Elanthius Flagstaff, Electro Burnstein, emiley tomsen, Escort DeFarge, Eva Rau, Ezian Ecksol, Fire Centaur, Fluf Fredriksson, Francisco Koolhoven, Frontera Thor, Frungi Stastny, Gally Young, gearsawe stonecutter, Gigs Taggart, Gordon Wendt, Gudmund Shepherd, Gypsy Paz, Harleen Gretzky, Henri Beauchamp, Inma Rau, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Jessicka Graves, Joeseph Albanese, Joshua Philgarlic, Khyota Wulluf, kirstenlee Cinquetti, Latif Khalifa, Lex Neva, Lilibeth Andree, Lisa Lowe, Lunita Savira, Loosey Demonia, lum pfohl, Marcos Fonzarelli, MartinRJ Fayray, Marusame Arai, Matthew Dowd, Maya Remblai, McCabe Maxsted, Meghan Dench, Melchoir Tokhes, Menos Short, Michelle2 Zenovka, Mimika Oh, Minerva Memel, Mm Alder, Ochi Wolfe, Omei Turnbull, Pesho Replacement, Phantom Ninetails, phoenixflames kukulcan, Polo Gufler, prez pessoa, princess niven, Prokofy Neva, Qie Niangao, Rem Beattie, RodneyLee Jessop, Saijanai Kuhn, Seg Baphomet, Sergen Davies, Shirley Marquez, SignpostMarv Martin, Sindy Tsure, Sira Arbizu, Skips Jigsaw, Sougent Harrop, Spritely Pixel, Squirrel Wood, StarSong Bright, Subversive Writer, Sugarcult Dagger, Sylumm Grigorovich, Tammy Nowotny, Tanooki Darkes, Tayra Dagostino, Theoretical Chemistry, Thickbrick Sleaford, valerie rosewood, Vex Streeter, Vixen Heron, Whoops Babii, Winter Ventura, Xiki Luik, Yann Dufaux, Yina Yao, Yukinoroh Kamachi, Zolute Infinity, Zwagoth Klaar
+
+
+Um im Geschäftsleben erfolreich zu sein, sei kühn, sei schnell, sei anders. --Henry Marchant
+ </text_editor>
+ </panel>
+ <panel name="licenses_panel">
+ <text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
APR Copyright (C) 2000-2004 The Apache Software Foundation
cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
@@ -25,10 +34,9 @@ google-perftools Copyright (c) 2005, Google Inc.
Alle Rechte vorbehalten. Details siehe licenses.txt.
Voice-Chat-Audiocoding: Polycom(R) Siren14(TM) (ITU-T Empf.G.722.1 Anhang C)
-
-
-Um im Geschäftsleben erfolreich zu sein, sei kühn, sei schnell, sei anders. --Henry Marchant
</text_editor>
+ </panel>
+</tab_container>
<text name="you_are_at">
Sie befinden sich in [POSITION]
</text>
diff --git a/indra/newview/skins/default/xui/de/floater_map.xml b/indra/newview/skins/default/xui/de/floater_map.xml
index a875d4aa90..97b3d76a46 100644
--- a/indra/newview/skins/default/xui/de/floater_map.xml
+++ b/indra/newview/skins/default/xui/de/floater_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Map">
- <floater.string name="mini_map_north">
- N
- </floater.string>
- <floater.string name="mini_map_east">
- O
- </floater.string>
- <floater.string name="mini_map_west">
- W
- </floater.string>
- <floater.string name="mini_map_south">
- S
- </floater.string>
- <floater.string name="mini_map_southeast">
- SO
- </floater.string>
- <floater.string name="mini_map_northeast">
- NO
- </floater.string>
- <floater.string name="mini_map_southwest">
- SW
- </floater.string>
- <floater.string name="mini_map_northwest">
- NW
- </floater.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="O" name="floater_map_east" text="O">
- O
- </text>
- <text label="W" name="floater_map_west" text="W">
- W
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SO" name="floater_map_southeast" text="SO">
- SO
- </text>
- <text label="NO" name="floater_map_northeast" text="NO">
- NO
- </text>
- <text label="SW" name="floater_map_southwest" text="SW">
- SW
- </text>
- <text label="NW" name="floater_map_northwest" text="NW">
- NW
- </text>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Map">
+ <floater.string name="mini_map_north">
+ N
+ </floater.string>
+ <floater.string name="mini_map_east">
+ O
+ </floater.string>
+ <floater.string name="mini_map_west">
+ W
+ </floater.string>
+ <floater.string name="mini_map_south">
+ S
+ </floater.string>
+ <floater.string name="mini_map_southeast">
+ SO
+ </floater.string>
+ <floater.string name="mini_map_northeast">
+ NO
+ </floater.string>
+ <floater.string name="mini_map_southwest">
+ SW
+ </floater.string>
+ <floater.string name="mini_map_northwest">
+ NW
+ </floater.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="O" name="floater_map_east" text="O">
+ O
+ </text>
+ <text label="W" name="floater_map_west" text="W">
+ W
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SO" name="floater_map_southeast" text="SO">
+ SO
+ </text>
+ <text label="NO" name="floater_map_northeast" text="NO">
+ NO
+ </text>
+ <text label="SW" name="floater_map_southwest" text="SW">
+ SW
+ </text>
+ <text label="NW" name="floater_map_northwest" text="NW">
+ NW
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml
index f84aa06b32..c7833f6936 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="advanced">
- <text name="AspectRatioLabel1" tool_tip="Breite/Höhe">
- Aspektverhältnis:
- </text>
- <combo_box name="aspect_ratio" tool_tip="Breite/Höhe">
- <combo_box.item label="4:3 (Standard-CRT)" name="item1"/>
- <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
- <combo_box.item label="8:5 (Widescreen)" name="item3"/>
- <combo_box.item label="16:9 (Widescreen)" name="item4"/>
- </combo_box>
-</panel>
+<?xml version="1.0" encoding="utf-8"?>
+<panel name="advanced">
+ <text name="AspectRatioLabel1" tool_tip="Breite/Höhe">
+ Aspektverhältnis:
+ </text>
+ <combo_box name="aspect_ratio" tool_tip="Breite/Höhe">
+ <combo_box.item label="4:3 (Standard-CRT)" name="item1"/>
+ <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
+ <combo_box.item label="8:5 (Widescreen)" name="item3"/>
+ <combo_box.item label="16:9 (Widescreen)" name="item4"/>
+ </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_world_map.xml b/indra/newview/skins/default/xui/de/panel_world_map.xml
index eaea377c0d..7b18c5e822 100644
--- a/indra/newview/skins/default/xui/de/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/de/panel_world_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="world_map">
- <panel.string name="world_map_north">
- N
- </panel.string>
- <panel.string name="world_map_east">
- O
- </panel.string>
- <panel.string name="world_map_west">
- W
- </panel.string>
- <panel.string name="world_map_south">
- S
- </panel.string>
- <panel.string name="world_map_southeast">
- SO
- </panel.string>
- <panel.string name="world_map_northeast">
- NO
- </panel.string>
- <panel.string name="world_map_southwest">
- SW
- </panel.string>
- <panel.string name="world_map_northwest">
- NW
- </panel.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="O" name="floater_map_east" text="O">
- O
- </text>
- <text label="W" name="floater_map_west" text="W">
- W
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SO" name="floater_map_southeast" text="SO">
- SO
- </text>
- <text label="NO" name="floater_map_northeast" text="NO">
- NO
- </text>
- <text label="SW" name="floater_map_southwest" text="SW">
- SW
- </text>
- <text label="NW" name="floater_map_northwest" text="NW">
- NW
- </text>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="world_map">
+ <panel.string name="world_map_north">
+ N
+ </panel.string>
+ <panel.string name="world_map_east">
+ O
+ </panel.string>
+ <panel.string name="world_map_west">
+ W
+ </panel.string>
+ <panel.string name="world_map_south">
+ S
+ </panel.string>
+ <panel.string name="world_map_southeast">
+ SO
+ </panel.string>
+ <panel.string name="world_map_northeast">
+ NO
+ </panel.string>
+ <panel.string name="world_map_southwest">
+ SW
+ </panel.string>
+ <panel.string name="world_map_northwest">
+ NW
+ </panel.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="O" name="floater_map_east" text="O">
+ O
+ </text>
+ <text label="W" name="floater_map_west" text="W">
+ W
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SO" name="floater_map_southeast" text="SO">
+ SO
+ </text>
+ <text label="NO" name="floater_map_northeast" text="NO">
+ NO
+ </text>
+ <text label="SW" name="floater_map_southwest" text="SW">
+ SW
+ </text>
+ <text label="NW" name="floater_map_northwest" text="NW">
+ NW
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/accordion_parent.xml b/indra/newview/skins/default/xui/en/accordion_parent.xml
index 914a6eddb9..ea34bac0a7 100644
--- a/indra/newview/skins/default/xui/en/accordion_parent.xml
+++ b/indra/newview/skins/default/xui/en/accordion_parent.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
- <panel border_thickness="2" name="splitter_parent"
+ <panel border_thickness="0" name="splitter_parent"
background_visible="true"
label="splitter_parent"
title=""
diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml
index e2f81168fa..dcd85e1f58 100644
--- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml
+++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml
@@ -6,9 +6,13 @@
halign="center"
height="23"
image_disabled="transparent.j2c"
- image_disabled_selected="PushButton_Selected"
- image_selected="PushButton_Selected"
- image_unselected="PushButton_Off"
+ image_disabled_selected="transparent.j2c"
+ image_selected="transparent.j2c"
+ image_unselected="transparent.j2c"
+ image_hover_selected="PushButton_Selected"
+ image_hover_unselected="PushButton_Off"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
hover_glow_amount="0.15"
layout="topleft"
left="2"
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 02a88fe5cc..9bc13ef0ba 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_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index f11391c5e0..5a285cdcb0 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1678,7 +1678,7 @@ Only large parcels can be listed in search.
height="16"
layout="topleft"
left="10"
- name="at URL:"
+ name="CurrentURL:"
top="49"
width="65">
Current URL:
diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
index 897e5da4e8..ef6af28786 100644
--- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
@@ -200,7 +200,7 @@
layout="topleft"
height="16"
left="10"
- name="Group:"
+ name="GroupLabel"
width="88">
Group:
</text>
@@ -218,7 +218,7 @@
follows="left|top"
height="16"
layout="topleft"
- name="NextOwnerLabel"
+ name="AnyoneLabel"
left="100"
top="110"
width="88">
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_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml
index 1592ed4aa4..0784b88944 100644
--- a/indra/newview/skins/default/xui/en/floater_camera.xml
+++ b/indra/newview/skins/default/xui/en/floater_camera.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
+ can_dock="true"
can_minimize="false"
can_close="false"
center_horiz="true"
@@ -29,6 +30,7 @@
layout="topleft"
left="0"
top="0"
+ mouse_opaque="false"
name="controls"
width="105">
<joystick_rotate
@@ -67,7 +69,7 @@
height="64"
image_unselected="cam_zoom_out.tga"
layout="topleft"
- left_delta="74"
+ left_delta="70"
minus_image="cam_zoom_minus_in.tga"
name="zoom"
picture_style="true"
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_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index a5d76821a8..be1278e8cc 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -9,7 +9,7 @@
help_topic="panel_im"
top="0"
can_dock="true"
- can_minimize="false"
+ can_minimize="true"
visible="true"
width="315">
<layout_stack follows="left|top|right|bottom"
diff --git a/indra/newview/skins/default/xui/en/floater_lagmeter.xml b/indra/newview/skins/default/xui/en/floater_lagmeter.xml
index 3f5127561a..2a431edcdd 100644
--- a/indra/newview/skins/default/xui/en/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/en/floater_lagmeter.xml
@@ -199,10 +199,10 @@
name="client"
top_delta="0"
width="128">
- Client:
+ Client
</text>
<text
- visiblity_control="LagMeterShrunk"
+ visiblity_control="LagMeterShrunk"
type="string"
length="1"
bottom="40"
@@ -216,7 +216,7 @@
Normal
</text>
<text
- visiblity_control="LagMeterShrunk"
+ visiblity_control="LagMeterShrunk"
bottom="56"
follows="left|top"
height="16"
@@ -248,10 +248,10 @@
name="network"
top_delta="0"
width="128">
- Network:
+ Network
</text>
<text
- visiblity_control="LagMeterShrunk"
+ visiblity_control="LagMeterShrunk"
type="string"
length="1"
bottom="80"
@@ -265,7 +265,7 @@
Normal
</text>
<text
- visiblity_control="LagMeterShrunk"
+ visiblity_control="LagMeterShrunk"
bottom="96"
follows="left|top"
height="16"
@@ -297,10 +297,10 @@
name="server"
top_delta="0"
width="60">
- Server:
+ Server
</text>
<text
- make_visible_control="LagMeterShrunk"
+ visiblity_control="LagMeterShrunk"
type="string"
length="1"
bottom="120"
@@ -308,13 +308,13 @@
font="SansSerif"
height="16"
layout="topleft"
- left="85"
+ left="110"
name="server_text"
right="-10">
Normal
</text>
<text
- make_visible_control="LagMeterShrunk"
+ visiblity_control="LagMeterShrunk"
bottom="136"
follows="left|top"
height="16"
@@ -322,7 +322,7 @@
left="40"
name="server_lag_cause"
right="-32" />
- <button
+ <!--button
bottom="145"
follows="left|top"
height="18"
@@ -330,16 +330,16 @@
layout="topleft"
name="server_help"
right="-10"
- width="18" />
+ width="18" /-->
<button
follows="left|top"
height="20"
label="&gt;&gt;"
layout="topleft"
- left_delta="-317"
+ left="10"
name="minimize"
- top_delta="-2"
- width="25">
+ top_delta="4"
+ width="40">
<button.commit_callback
function="LagMeter.ClickShrink" />
</button>
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_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml
index dc0ff7ac4c..82acea47be 100644
--- a/indra/newview/skins/default/xui/en/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/en/floater_moveview.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
+ can_dock="true"
can_close="false"
can_minimize="false"
center_horiz="true"
@@ -41,6 +42,7 @@
follows="left|top"
layout="topleft"
left="0"
+ mouse_opaque="false"
name="panel_actions"
top="0"
width="115">
@@ -95,7 +97,7 @@
scale_image="false"
tool_tip="Fly Down, Press &quot;C&quot;"
top_delta="0"
- width="25" />
+ width="20" />
<joystick_turn
follows="left|bottom"
height="25"
diff --git a/indra/newview/skins/default/xui/en/floater_mute_object.xml b/indra/newview/skins/default/xui/en/floater_mute_object.xml
index 412df1d262..06a03ff340 100644
--- a/indra/newview/skins/default/xui/en/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_mute_object.xml
@@ -1,56 +1,63 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
can_minimize="false"
- height="140"
+ height="130"
layout="topleft"
- name="mute by name"
+ name="block by name"
help_topic="mute_by_name"
title="Block object by name"
width="375">
<text
type="string"
length="1"
- bottom_delta="50"
follows="top|left"
- font="SansSerif"
+ font="SansSerifLarge"
height="16"
layout="topleft"
- left="20"
- left_delta="25"
- name="message"
- right="380">
- Block by name only affects object chat and IM, not sounds.
-You must type the object&apos;s name exactly.
+ left="10"
+ top="25"
+ name="message">
+ Block an object:
</text>
<line_editor
type="string"
length="1"
follows="top|right"
font="SansSerif"
- height="18"
+ height="20"
layout="topleft"
left_delta="0"
name="object_name"
- top_pad="22"
- width="320">
+ top_pad="5"
+ width="350">
Object name
</line_editor>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifSmall"
+ height="16"
+ layout="topleft"
+ left="30"
+ name="note">
+ * Only blocks object text, not sounds
+ </text>
<button
follows="bottom|left"
- height="20"
+ height="23"
label="Ok"
layout="topleft"
- left="108"
+ left="155"
name="OK"
- top="100"
- width="75" />
+ top_pad="10"
+ width="100" />
<button
follows="bottom|right"
- height="20"
+ height="23"
label="Cancel"
layout="topleft"
- left_pad="7"
+ left_pad="5"
name="Cancel"
- top_delta="0"
- width="75" />
+ width="100" />
</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 3f31641cac..aef5707fd4 100644
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -11,44 +11,21 @@
title="NOTIFICATIONS"
width="320"
min_width="320"
- height="60"
- can_minimize="false"
+ height="23"
+ can_minimize="true"
can_tear_off="false"
can_resize="false"
can_drag_on_left="false"
can_close="false"
can_dock="true"
>
- <scroll_container
- follows="top|bottom"
- layout="topleft"
- name="notification_list_container"
- left="0"
- top="18"
- width="320"
- height="42">
- <panel
- layout="topleft"
- name="twin_list_panel"
- left="1"
- top="0"
- width="318"
- height="32"
- bg_alpha_color="1.0 1.0 1.0 1.0">
- <scrolling_panel_list
- layout="topleft"
- name="notification_list"
- left="1"
- top="0"
- height="0"
- width="318"/>
- <scrolling_panel_list
- layout="topleft"
- name="im_row_panel_list"
- left="1"
- top="2"
- height="0"
- width="318"/>
- </panel>
-</scroll_container>
+ <flat_list_view
+ color="FloaterDefaultBackgroundColor"
+ follows="all"
+ layout="topleft"
+ name="notification_list"
+ left="1"
+ top="20"
+ 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_ui_preview.xml b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
index 2c14b3d87a..9a3d5aa183 100644
--- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
@@ -48,8 +48,8 @@
<button
follows="left|top"
height="25"
- label="Display Floater"
- label_selected="Display Floater"
+ label="Show"
+ label_selected="Show"
layout="topleft"
left_pad="10"
name="display_floater"
@@ -60,8 +60,8 @@
enabled="false"
follows="left|top"
height="25"
- label="Close Floater"
- label_selected="Close Floater"
+ label="Hide"
+ label_selected="Hide"
layout="topleft"
left_pad="10"
name="close_displayed_floater"
@@ -71,8 +71,8 @@
<button
follows="left|top"
height="25"
- label="Edit Floater..."
- label_selected="Edit Floater..."
+ label="Edit..."
+ label_selected="Edit..."
layout="topleft"
left_pad="10"
name="edit_floater"
@@ -144,8 +144,7 @@
<button
follows="left|top"
height="25"
- label="Display Floater"
- label_selected="Display Floater"
+ label="Show"
layout="topleft"
left_pad="10"
name="display_floater_2"
@@ -156,8 +155,7 @@
enabled="false"
follows="left|top"
height="25"
- label="Close Floater"
- label_selected="Close Floater"
+ label="Hide"
layout="topleft"
left_pad="10"
name="close_displayed_floater_2"
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_bottomtray.xml b/indra/newview/skins/default/xui/en/menu_bottomtray.xml
new file mode 100644
index 0000000000..e98920f8c2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_bottomtray.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="201"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="hide_camera_move_controls_menu"
+ top="624"
+ visible="false"
+ width="128">
+ <menu_item_check
+ label="Gesture button"
+ layout="topleft"
+ name="ShowGestureButton">
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowGestureButton" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowGestureButton" />
+ </menu_item_check>
+ <menu_item_check
+ label="Move button"
+ layout="topleft"
+ name="ShowMoveButton">
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowMoveButton" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowMoveButton" />
+ </menu_item_check>
+ <menu_item_check
+ label="Camera button"
+ layout="topleft"
+ name="ShowCameraButton">
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowCameraButton" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowCameraButton" />
+ </menu_item_check>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_hide_navbar.xml b/indra/newview/skins/default/xui/en/menu_hide_navbar.xml
index 1ad10abbeb..a175b3103f 100644
--- a/indra/newview/skins/default/xui/en/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/en/menu_hide_navbar.xml
@@ -11,23 +11,23 @@
<menu_item_check
label="Show Navigation Bar"
layout="topleft"
- name="Show Navigation Bar">
+ name="ShowNavbarNavigationPanel">
<menu_item_check.on_click
- function="HideNavbarMenu.Action"
- parameter="show_navbar_navigation_panel" />
+ function="ToggleControl"
+ parameter="ShowNavbarNavigationPanel" />
<menu_item_check.on_check
- function="HideNavbarMenu.EnableMenuItem"
- parameter="show_navbar_navigation_panel" />
+ function="CheckControl"
+ parameter="ShowNavbarNavigationPanel" />
</menu_item_check>
<menu_item_check
label="Show Favorites Bar"
layout="topleft"
- name="Show Favorites Bar">
+ name="ShowNavbarFavoritesPanel">
<menu_item_check.on_click
- function="HideNavbarMenu.Action"
- parameter="show_navbar_favorites_panel" />
+ function="ToggleControl"
+ parameter="ShowNavbarFavoritesPanel" />
<menu_item_check.on_check
- function="HideNavbarMenu.EnableMenuItem"
- parameter="show_navbar_favorites_panel" />
+ function="CheckControl"
+ parameter="ShowNavbarFavoritesPanel" />
</menu_item_check>
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 7a0a78bb50..d3a2b2c66b 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -234,7 +234,7 @@
<menu_item_call
label="Show Critical Message"
layout="topleft"
- name="TOS">
+ name="Critical">
<menu_item_call.on_click
function="ShowFloater"
parameter="message_critical" />
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
new file mode 100644
index 0000000000..ec8582f5b5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true">
+ <menu_item_check
+ label="Display Group Icons"
+ layout="topleft"
+ name="Display Group Icons">
+ <menu_item_check.on_click
+ function="People.Groups.ViewSort.Action"
+ parameter="show_icons" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="GroupListShowIcons" />
+ </menu_item_check>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
new file mode 100644
index 0000000000..643336cf6c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Avatar Context Menu">
+ <menu_item_call
+ label="View Profile"
+ layout="topleft"
+ name="View Profile">
+ <menu_item_call.on_click
+ function="Avatar.Profile" />
+ </menu_item_call>
+ <menu_item_call
+ label="Add Friend"
+ layout="topleft"
+ name="Add Friend">
+ <menu_item_call.on_click
+ function="Avatar.AddFriend" />
+ <menu_item_call.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_add" />
+ </menu_item_call>
+ <menu_item_call
+ label="IM"
+ layout="topleft"
+ name="IM">
+ <menu_item_call.on_click
+ function="Avatar.IM" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Call"
+ layout="topleft"
+ name="Call">
+ <menu_item_call.on_click
+ function="Avatar.Call" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Share"
+ layout="topleft"
+ name="Share">
+ <menu_item_call.on_click
+ function="Avatar.Share" />
+ </menu_item_call>
+ <menu_item_call
+ label="Pay"
+ layout="topleft"
+ name="Pay">
+ <menu_item_call.on_click
+ function="Avatar.Pay" />
+ </menu_item_call>
+ <menu_item_check
+ label="Block/Unblock"
+ layout="topleft"
+ name="Block/Unblock">
+ <menu_item_check.on_click
+ function="Avatar.BlockUnblock" />
+ <menu_item_check.on_check
+ function="Avatar.CheckItem"
+ parameter="is_blocked" />
+ <menu_item_check.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_block" />
+ </menu_item_check>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
index 88b0528e53..d9606de90d 100644
--- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
@@ -2,8 +2,8 @@
<menu name="menu_group_plus"
left="0" bottom="0" visible="false"
mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true">
- <menu_item_call name="sort_most" label="Sort by Most Speakers">
- <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="sort_most" />
+ <menu_item_call name="sort_most" label="Sort by Most Recent">
+ <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="sort_recent" />
</menu_item_call>
<menu_item_call name="sort_name" label="Sort by Name">
<menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="sort_name" />
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 b430de2b7b..2c77f61da6 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -127,12 +127,14 @@
<menu_item_call.on_click
function="World.SetAway" />
</menu_item_call>
+ <menu_item_separator
+ 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
@@ -381,7 +383,7 @@
<menu_item_check.on_click
function="Floater.Toggle"
parameter="world_map" />
- </menu_item_check>
+ </menu_item_check>
<menu_item_check
label="Mini-Map"
layout="topleft"
@@ -395,7 +397,31 @@
parameter="mini_map" />
</menu_item_check>
<menu_item_separator
- layout="topleft" />
+ layout="topleft" />
+ <menu_item_check
+ label="Show Navigation Bar"
+ layout="topleft"
+ name="ShowNavbarNavigationPanel">
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowNavbarNavigationPanel" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowNavbarNavigationPanel" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Favorites Bar"
+ layout="topleft"
+ name="ShowNavbarFavoritesPanel">
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowNavbarFavoritesPanel" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowNavbarFavoritesPanel" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
<menu_item_call
label="Take Snapshot"
layout="topleft"
@@ -466,8 +492,6 @@
parameter="editor" />
</menu_item_call>
</menu>
- <menu_item_separator
- layout="topleft" />
</menu>
<menu
create_jump_keys="true"
@@ -820,14 +844,14 @@
function="Floater.Toggle"
parameter="perm_prefs" />
</menu_item_call>
- <menu_item_call
+ <!--menu_item_call
label="Show Script Warning/Error Window"
layout="topleft"
name="Show Script Warning/Error Window">
<menu_item_call.on_click
function="ShowFloater"
parameter="script errors" />
- </menu_item_call>
+ </menu_item_call-->
<menu_item_separator
layout="topleft" />
<menu
@@ -1018,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">
@@ -2747,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 80d501b63e..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"
@@ -996,6 +1023,17 @@ There was a problem saving a compiled script due to the following reason: [REASO
<notification
icon="alertmodal.tga"
+ name="StartRegionEmpty"
+ type="alertmodal">
+Oops, Your Start Region is not defined.
+Please type the Region name in Start Location box or choose My Last Location or My Home as your Start Location.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="CouldNotStartStopScript"
type="alertmodal">
Could not start or stop the script because the object it is on could not be found.
@@ -1204,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/
@@ -1680,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
@@ -1761,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
@@ -1835,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
@@ -1845,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
@@ -1962,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
@@ -2747,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.
@@ -4264,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.
@@ -4288,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.
@@ -4320,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.
@@ -4337,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,
@@ -6536,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_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index f211ae0ad6..d5ed0c986d 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -38,7 +38,7 @@
width="20" />
<text
follows="left|right"
- font="SansSerifBigBold"
+ font="SansSerifSmallBold"
height="20"
layout="topleft"
left_pad="5"
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 6449059ef0..cd7e340ff1 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- mouse_opaque="false"
+ mouse_opaque="true"
background_visible="true"
bg_alpha_color="0.25 0.25 0.25 1"
bg_opaque_color="0.25 0.25 0.25 1"
@@ -36,13 +36,13 @@
width="5"/>
<layout_panel
mouse_opaque="false"
- auto_resize="false"
+ auto_resize="true"
follows="left|right"
height="28"
layout="topleft"
left="5"
min_height="28"
- width="600"
+ width="450"
top="0"
min_width="305"
name="chat_bar"
@@ -79,7 +79,6 @@
label="Move"
layout="topleft"
name="movement_btn"
- tab_stop="false"
tool_tip="Shows/Hide Movement controls"
top="6"
width="70">
@@ -110,47 +109,13 @@
name="cam_panel"
top_delta="-10"
width="150">
- <split_button
- follows="right"
- height="18"
- name="presets"
- top="6"
- width="35">
- <split_button.arrow_button
- image_selected="camera_presets/camera_presets_arrow.png"
- image_unselected="camera_presets/camera_presets_arrow.png"
- image_disabled_selected="camera_presets/camera_presets_arrow.png"
- image_disabled="camera_presets/camera_presets_arrow.png"
- name="camera_presets"
- tool_tip="Camera Presets"
- />
- <split_button.item
- image_selected="camera_presets/camera_presets_rear_view.png"
- image_unselected="camera_presets/camera_presets_rear_view.png"
- name="rear_view"
- tool_tip="Rear View"
- />
- <split_button.item
- image_selected="camera_presets/camera_presets_34_view.png"
- image_unselected="camera_presets/camera_presets_34_view.png"
- name="group_view"
- tool_tip="Group View"
- />
- <split_button.item
- image_selected="camera_presets/camera_presets_fron_view.png"
- image_unselected="camera_presets/camera_presets_fron_view.png"
- name="front_view"
- tool_tip="Front View"
- />
- </split_button>
<button
follows="right"
height="20"
is_toggle="true"
- label="Camera"
+ label="View"
layout="topleft"
- left_pad="0"
- tab_stop="false"
+ left="0"
tool_tip="Shows/Hide Camera controls"
top="6"
name="camera_btn"
@@ -159,11 +124,27 @@
function="Button.SetFloaterToggle"
parameter="camera" />
</button>
+ <button
+ follows="right"
+ name="camera_presets_btn"
+ top="6"
+ height="20"
+ width="20"
+ left_pad="0"
+ is_toggle="true"
+ picture_style="true"
+ image_selected="toggle_button_selected"
+ image_unselected="toggle_button_off">
+ <button.init_callback
+ function="Button.SetFloaterToggle"
+ parameter="camera_presets"
+ />
+ </button>
<split_button
arrow_position="right"
follows="right"
height="18"
- left_pad="0"
+ left_pad="4"
name="snapshots"
top="6"
width="35">
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 311caa4866..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
@@ -16,7 +16,10 @@
name="want_apply_text">
Do you want to apply these changes?
</panel.string>
-
+ <panel.string
+ name="group_join_btn">
+ Join (L$[AMOUNT])
+ </panel.string>
<button
layout="topleft"
name="back"
@@ -25,7 +28,7 @@
width="25"
height="25"
label=""
- follows="top|left"
+ follows="top|right"
image_overlay="BackArrow_Off"
tab_stop="false" />
<text
@@ -38,7 +41,20 @@
text_color="white"
follows="top|left|right"
mouse_opaque="true"
+ use_ellipses="true"
name="group_name">(Loading...)</text>
+ <line_editor
+ follows="left|top"
+ font="SansSerif"
+ label="Type your new group name here"
+ layout="topleft"
+ left_delta="0"
+ max_length="35"
+ name="group_name_editor"
+ top_delta="5"
+ width="250"
+ height="20"
+ visible="true" />
<texture_picker
follows="left|top"
height="113"
@@ -47,7 +63,7 @@
left="10"
name="insignia"
tool_tip="Click to choose a picture"
- top_pad="15"
+ top_pad="5"
width="100" />
<text
type="string"
@@ -72,11 +88,21 @@
use_ellipses="true"
width="140" />
<button
+ follows="left|top"
+ left_delta="0"
+ top_pad="10"
+ height="20"
+ label="Join"
+ label_selected="Join"
+ name="btn_join"
+ visible="true"
+ width="65" />
+ <button
top="632"
height="20"
font="SansSerifSmall"
- label="Apply"
- label_selected="Apply"
+ label="Save"
+ label_selected="Save"
name="btn_apply"
left="5"
width="65" />
@@ -93,13 +119,21 @@
<button
top="632"
height="20"
- font="SansSerifSmall"
label="Create"
label_selected="Create"
name="btn_create"
left="5"
visible="false"
width="65" />
+ <button
+ top="632"
+ left="75"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ name="btn_cancel"
+ visible="false"
+ width="65" />
<accordion layout="topleft" left="2" width="296" top="135" height="500" follows="all" name="group_accordion">
<accordion_tab min_height="445" title="Group General" name="group_general_tab">
<panel class="panel_group_general" filename="panel_group_general.xml" name="group_general_tab_panel"/>
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
new file mode 100644
index 0000000000..3f49bfad36
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="24"
+ layout="topleft"
+ left="0"
+ name="group_list_item"
+ top="0"
+ width="320">
+ <icon
+ follows="top|right|left"
+ height="24"
+ image_name="ListItem_Over"
+ layout="topleft"
+ left="0"
+ name="hovered_icon"
+ top="0"
+ visible="false"
+ width="320" />
+ <icon
+ height="24"
+ follows="top|right|left"
+ image_name="ListItem_Select"
+ layout="topleft"
+ left="0"
+ name="selected_icon"
+ top="0"
+ visible="false"
+ width="320" />
+ <icon
+ follows="top|left"
+ height="18"
+ image_name="icon_group.tga"
+ layout="topleft"
+ left="5"
+ mouse_opaque="true"
+ name="group_icon"
+ top="4"
+ width="18" />
+ <text
+ follows="left|right"
+ font="SansSerifSmall"
+ height="17"
+ layout="topleft"
+ left_pad="5"
+ name="group_name"
+ text_color="white"
+ top="7"
+ use_ellipses="true"
+ value="Unknown"
+ width="263" />
+ <button
+ follows="right"
+ height="18"
+ image_disabled="Info"
+ image_disabled_selected="Info"
+ image_hover_selected="Info"
+ image_selected="Info"
+ image_unselected="Info"
+ layout="topleft"
+ name="info_btn"
+ picture_style="true"
+ right="-5"
+ top="4"
+ width="18" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml
index ace456918c..7db1b9e916 100644
--- a/indra/newview/skins/default/xui/en/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml
@@ -33,7 +33,17 @@
layout="topleft"
left="5"
mouse_opaque="true"
- name="avatar"
+ name="avatar_icon"
+ top="5"
+ width="20" />
+ <icon
+ follows="right"
+ height="20"
+ image_name="icon_top_pick.tga"
+ layout="topleft"
+ left="5"
+ mouse_opaque="true"
+ name="sys_msg_icon"
top="5"
width="20" />
<text
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index d943b2ea23..c96c296057 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- follows="left|top|right|bottom"
+ follows="all"
height="600"
layout="topleft"
left="0"
@@ -22,13 +22,12 @@
<web_browser
border_visible="false"
bottom="600"
- follows="top|left|bottom|right"
+ follows="all"
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"
@@ -44,10 +43,7 @@
First Name:
</text>
<line_editor
- border_style="line"
- border_thickness="1"
follows="left|bottom"
- font="SansSerif"
handle_edit_keys_directly="true"
height="20"
layout="topleft"
@@ -55,8 +51,8 @@
max_length="31"
name="first_name_edit"
select_on_focus="true"
- tool_tip="Enter first name here"
- top_pad="4"
+ tool_tip="[SECOND_LIFE] First Name"
+ top_pad="2"
width="120" />
<text
type="string"
@@ -72,8 +68,6 @@
Last Name:
</text>
<line_editor
- border_style="line"
- border_thickness="1"
follows="left|bottom"
font="SansSerif"
handle_edit_keys_directly="true"
@@ -83,7 +77,8 @@
max_length="31"
name="last_name_edit"
select_on_focus="true"
- top_pad="4"
+ tool_tip="[SECOND_LIFE] Last Name"
+ top_pad="2"
width="120" />
<text
type="string"
@@ -99,8 +94,6 @@
Password:
</text>
<line_editor
- border_style="line"
- border_thickness="1"
follows="left|bottom"
font="SansSerif"
handle_edit_keys_directly="true"
@@ -110,27 +103,26 @@
max_length="16"
name="password_edit"
select_on_focus="true"
- top_pad="4"
+ top_pad="2"
width="120" />
<button
follows="left|bottom"
- height="24"
+ height="23"
label="Log In"
label_selected="Log In"
layout="topleft"
- left="435"
+ left="425"
name="connect_btn"
- top="548"
- width="120" />
+ top="546"
+ width="100" />
<combo_box
allow_text_entry="true"
follows="left|bottom"
- height="18"
+ height="23"
layout="topleft"
- left_pad="15"
+ left_pad="5"
name="server_combo"
- top_delta="2"
- width="120" />
+ width="100" />
<text
type="string"
length="1"
@@ -142,15 +134,15 @@
name="start_location_text"
top="576"
width="95">
- Start Location:
+ Start location:
</text>
<combo_box
allow_text_entry="true"
control_name="LoginLocation"
follows="left|bottom"
- height="18"
+ height="23"
layout="topleft"
- left_pad="2"
+ left_pad="0"
max_chars="128"
name="start_location_combo"
top_delta="-2"
@@ -172,13 +164,12 @@
control_name="RememberPassword"
follows="left|bottom"
height="16"
- label="Remember password"
+ label="Remember me"
layout="topleft"
left_pad="10"
name="remember_check"
top_delta="3"
width="138" />
-
<text
type="string"
length="1"
@@ -192,7 +183,7 @@
name="create_new_account_text"
top="539"
width="200">
- Sign up for account
+ Create a new account
</text>
<text
type="string"
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_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 13ceab7604..1178d75b2c 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -135,6 +135,7 @@
layout="topleft"
left="5"
name="favorite"
+ image_drag_indication="Arrow_Down"
chevron_button_tool_tip="Show more of My Favorites"
top="32"
width="590" />
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_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 132a2d1dc5..786c39c5e9 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -127,7 +127,6 @@ color="DkGray"
name="tab_online"
title="Online">
<avatar_list
- draw_heading="false"
follows="all"
height="150"
layout="topleft"
@@ -143,7 +142,6 @@ color="DkGray"
name="tab_all"
title="All">
<avatar_list
- draw_heading="false"
follows="all"
height="230"
layout="topleft"
@@ -219,7 +217,6 @@ color="DkGray"
name="groups_panel"
width="313">
<group_list
- draw_heading="false"
follows="left|top|right|bottom"
height="357"
layout="topleft"
@@ -240,7 +237,6 @@ color="DkGray"
name="bottom_panel"
width="313">
<button
- enabled="false"
follows="bottom|left"
font="SansSerifBigBold"
tool_tip="Change sort and view of Groups list"
@@ -250,7 +246,7 @@ color="DkGray"
image_unselected="OptionsMenu_Off"
layout="topleft"
left="10"
- name="gear_btn"
+ name="groups_viewsort_btn"
picture_style="true"
top="5"
width="18" />
@@ -307,7 +303,7 @@ color="DkGray"
layout="topleft"
name="recent_panel"
width="313">
- <avatar_list_tmp
+ <avatar_list
color="DkGray2"
follows="left|top|right|bottom"
height="357"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
index 37e873b6a8..686faab8eb 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
@@ -9,6 +9,7 @@
top="0"
width="305">
<icon
+ follows="top|bottom|left|right"
height="120"
image_name="ListItem_Over"
left="0"
@@ -19,6 +20,7 @@
visible="false"
width="305"/>
<icon
+ follows="top|bottom|left|right"
height="120"
image_name="ListItem_Select"
left="0"
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index bceaedcdb4..1bd1953397 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -1,31 +1,23 @@
<?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"
name="panel_picks"
top="0"
width="313">
- <scroll_container
+ <flat_list_view
color="DkGray2"
follows="left|top|right|bottom"
- height="495"
+ height="465"
layout="topleft"
left="0"
- name="profile_scroll"
+ name="picks_list"
opaque="true"
top="0"
- width="313">
- <list
- height="120"
- layout="topleft"
- left="0"
- name="picks_list"
- top="0"
- width="305" />
- </scroll_container>
+ width="313" />
<panel
background_visible="true"
bevel_style="none"
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 b492ee1dc3..06ecfdc995 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -18,13 +18,13 @@
name="aspect_ratio_text">
[NUM]:[DEN]
</panel.string>
- <check_box
+ <check_box
control_name="UseChatBubbles"
height="16"
label="Bubble Chat"
layout="topleft"
left="30"
- top="20"
+ top="10"
name="bubble_text_chat"
width="150" />
@@ -35,7 +35,7 @@
initial_value="1"
label="Opacity"
layout="topleft"
- left="50"
+ left_delta="50"
top_pad="5"
label_width="50"
name="bubble_chat_opacity"
@@ -73,7 +73,7 @@
</text>
<combo_box
allow_text_entry="true"
- height="25"
+ height="20"
layout="topleft"
left_pad="0"
max_chars="100"
@@ -119,9 +119,8 @@
length="1"
height="10"
left="30"
- text_color="EmphasisColor"
name="heading1"
- top_pad="30"
+ top_pad="10"
width="270">
Camera:
</text>
@@ -137,13 +136,12 @@ Camera:
layout="topleft"
label_width="100"
label="View Angle"
- left="30"
+ left_delta="50"
max_val="2.97"
min_val="0.17"
name="camera_fov"
show_text="false"
width="240" />
-
<slider
can_edit_text="true"
control_name="CameraOffsetScale"
@@ -154,13 +152,14 @@ Camera:
initial_value="1"
layout="topleft"
label="Distance"
- left="30"
+ left_delta="0"
label_width="100"
max_val="3"
min_val="0.5"
name="camera_offset_scale"
show_text="false"
- width="240" />
+ width="240"
+ top_pad="10"/>
<text
type="string"
length="1"
@@ -175,10 +174,11 @@ Automatic positioning for:
height="20"
label="Build/Edit"
layout="topleft"
- left="50"
+ left_delta="50"
name="edit_camera_movement"
tool_tip="Use automatic camera positioning when entering and exiting edit mode"
- width="280" />
+ width="280"
+ top_pad="10" />
<check_box
control_name="AppearanceCameraMovement"
height="16"
@@ -193,9 +193,8 @@ Automatic positioning for:
length="1"
height="10"
left="30"
- text_color="EmphasisColor"
name="heading3"
- top_pad="30"
+ top_pad="10"
width="270">
My Avatar:
</text>
@@ -204,24 +203,28 @@ My Avatar:
height="20"
label="Show me in Mouselook"
layout="topleft"
+ left_delta="50"
name="first_person_avatar_visible"
- width="256" />
+ width="256"
+ top_pad="10"/>
<check_box
control_name="ArrowKeysMoveAvatar"
height="20"
label="Arrow keys always move me"
layout="topleft"
- left="30"
+ left_delta="0"
name="arrow_keys_move_avatar_check"
- width="237" />
+ width="237"
+ top_pad="0"/>
<check_box
control_name="TapTapHoldtoRun"
height="20"
label="Tap-tap-hold to run"
layout="topleft"
- left="30"
+ left_delta="0"
name="tap_tap_hold_to_run"
- width="237" />
+ width="237"
+ top_pad="0"/>
<!--menu_item_check
label="Tap-Tap-Hold to Run"
layout="topleft"
@@ -237,9 +240,10 @@ My Avatar:
height="20"
label="Move my avatar's lips when speaking"
layout="topleft"
- left="30"
+ left_delta="0"
name="enable_lip_sync"
- width="237" />
+ width="237"
+ top_pad="0" />
<!--menu_item_check
label="Enable Lip Sync(Beta)"
layout="topleft"
@@ -251,6 +255,42 @@ My Avatar:
function="ToggleControl"
parameter="LipSyncEnabled" />
</menu_item_check-->
+ <check_box
+ control_name="test"
+ height="20"
+ label="Show script errors"
+ layout="topleft"
+ left="30"
+ name="show_script_errors"
+ width="256"
+ top_pad="10"/>
+ <radio_group
+ enabled_control="EnableShowScriptErrors"
+ control_name="ShowScriptErrorsLocation"
+ draw_border="false"
+ height="40"
+ layout="topleft"
+ left_delta="50"
+ name="show_location"
+ top_pad="5"
+ width="364">
+ <radio_item
+ height="16"
+ label="In chat"
+ layout="topleft"
+ left="3"
+ name="0"
+ top="3"
+ width="315" />
+ <radio_item
+ height="16"
+ label="In window"
+ layout="topleft"
+ left_delta="0"
+ name="1"
+ top_delta="16"
+ width="315" />
+ </radio_group>
</panel> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index 7f72c7b0e9..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"
@@ -72,15 +72,16 @@
top_delta="0"
value="[SECOND_LIFE]:"
width="170" />
- <text
+ <expandable_text
follows="left|top|right"
height="90"
layout="topleft"
name="sl_description_edit"
width="170"
- word_wrap="true">
+ expanded_bg_visible="true"
+ expanded_bg_color="black">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
- </text>
+ </expandable_text>
</panel>
<panel
follows="left|top"
@@ -112,15 +113,16 @@
top_delta="0"
value="Real World:"
width="175" />
- <text
+ <expandable_text
follows="left|top|right"
height="90"
layout="topleft"
name="fl_description_edit"
width="180"
- word_wrap="true">
+ expanded_bg_visible="true"
+ expanded_bg_color="black">
Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
- </text>
+ </expandable_text>
</panel>
<text
type="string"
@@ -263,6 +265,7 @@
left="0"
name="profile_buttons_panel"
top_pad="0"
+ height="25"
width="313">
<button
follows="bottom|left"
@@ -314,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 a5c3be3349..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
@@ -4,6 +4,7 @@
bottom="0"
follows="left|top|right"
height="30"
+ width="305"
layout="topleft"
left="0"
name="sidetray_tab_panel">
@@ -18,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_sys_well_item.xml b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
index 3ac15fe550..53ee0d159d 100644
--- a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
@@ -4,7 +4,7 @@
<panel
name="sys_well_item"
title="sys_well_item"
- visible="false"
+ visible="true"
top="0"
left="0"
width="318"
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 70198dc626..aa95a2baef 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -13,10 +13,9 @@
<accordion_tab
can_resize="false"
layout="topleft"
- min_height="100"
name="today"
title="Today">
- <scroll_list
+ <flat_list_view
draw_heading="false"
follows="all"
height="150"
@@ -24,20 +23,16 @@
left="0"
name="today_items"
top="0"
- width="285">
- <column name="landmark_icon" width="20" />
- <column dynamic_width="true" label="Region" name="region" />
- <column name="index" width="0" />
- </scroll_list>
+ width="380">
+ </flat_list_view>
</accordion_tab>
<accordion_tab
can_resize="false"
layout="topleft"
- min_height="100"
name="yesterday"
title="Yesterday">
- <scroll_list
+ <flat_list_view
draw_heading="false"
follows="all"
height="150"
@@ -45,20 +40,33 @@
left="0"
name="yesterday_items"
top="0"
- width="285">
- <column name="landmark_icon" width="20" />
- <column dynamic_width="true" label="Region" name="region" />
- <column name="index" width="0" />
- </scroll_list>
+ width="380">
+ </flat_list_view>
+ </accordion_tab>
+
+ <accordion_tab
+ can_resize="false"
+ layout="topleft"
+ name="2_days_ago"
+ title="2 days ago">
+ <flat_list_view
+ draw_heading="false"
+ follows="all"
+ height="150"
+ layout="topleft"
+ left="0"
+ name="2_days_ago"
+ top="0"
+ width="380">
+ </flat_list_view>
</accordion_tab>
<accordion_tab
can_resize="false"
layout="topleft"
- min_height="100"
name="3_days_ago"
title="3 days ago">
- <scroll_list
+ <flat_list_view
draw_heading="false"
follows="all"
height="150"
@@ -66,20 +74,16 @@
left="0"
name="3_days_ago"
top="0"
- width="285">
- <column name="landmark_icon" width="20" />
- <column dynamic_width="true" label="Region" name="region" />
- <column name="index" width="0" />
- </scroll_list>
+ width="380">
+ </flat_list_view>
</accordion_tab>
<accordion_tab
can_resize="false"
layout="topleft"
- min_height="100"
name="4_days_ago"
title="4 days ago">
- <scroll_list
+ <flat_list_view
draw_heading="false"
follows="all"
height="150"
@@ -87,20 +91,16 @@
left="0"
name="4_days_ago"
top="0"
- width="285">
- <column name="landmark_icon" width="20" />
- <column dynamic_width="true" label="Region" name="region" />
- <column name="index" width="0" />
- </scroll_list>
+ width="380">
+ </flat_list_view>
</accordion_tab>
<accordion_tab
can_resize="false"
layout="topleft"
- min_height="100"
name="5_days_ago"
title="5 days ago">
- <scroll_list
+ <flat_list_view
draw_heading="false"
follows="all"
height="150"
@@ -108,55 +108,59 @@
left="0"
name="5_days_ago_items"
top="0"
- width="285">
- <column name="landmark_icon" width="20" />
- <column dynamic_width="true" label="Region" name="region" />
- <column name="index" width="0" />
- </scroll_list>
+ width="380">
+ </flat_list_view>
</accordion_tab>
-
+
<accordion_tab
can_resize="false"
layout="topleft"
- min_height="100"
- name="6_days_ago"
- title="6 days ago">
- <scroll_list
+ name="6_days_and_older"
+ title="6 days and older">
+ <flat_list_view
draw_heading="false"
follows="all"
height="150"
layout="topleft"
left="0"
- name="6_days_ago"
+ name="6_days_and_older_items"
top="0"
- width="285">
- <column name="landmark_icon" width="20" />
- <column dynamic_width="true" label="Region" name="region" />
- <column name="index" width="0" />
- </scroll_list>
+ width="380">
+ </flat_list_view>
</accordion_tab>
-
+
<accordion_tab
can_resize="false"
layout="topleft"
- min_height="100"
- name="older_than_6_days"
- title="Older than 6 days">
- <scroll_list
+ name="1_month_and_older"
+ title="1 month and older">
+ <flat_list_view
draw_heading="false"
follows="all"
height="150"
layout="topleft"
left="0"
- name="older_than_6_days_items"
+ name="1_month_and_older_items"
top="0"
- width="285">
- <column name="landmark_icon" width="20" />
- <column dynamic_width="true" label="Region" name="region" />
- <column name="index" width="0" />
- </scroll_list>
+ width="380">
+ </flat_list_view>
</accordion_tab>
-
+
+ <accordion_tab
+ can_resize="false"
+ layout="topleft"
+ name="6_months_and_older"
+ title="6 months and older">
+ <flat_list_view
+ draw_heading="false"
+ follows="all"
+ height="150"
+ layout="topleft"
+ left="0"
+ name="6_months_and_older_items"
+ top="0"
+ width="380">
+ </flat_list_view>
+ </accordion_tab>
</accordion>
-
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
new file mode 100644
index 0000000000..bb37f43220
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="20"
+ layout="topleft"
+ left="0"
+ name="teleport_history_item"
+ top="0"
+ width="380">
+ <icon
+ follows="top|right|left"
+ height="20"
+ image_name="ListItem_Over"
+ layout="topleft"
+ left="0"
+ name="hovered_icon"
+ top="0"
+ visible="false"
+ width="380" />
+ <icon
+ height="20"
+ follows="top|right|left"
+ image_name="ListItem_Select"
+ layout="topleft"
+ left="0"
+ name="selected_icon"
+ top="0"
+ visible="false"
+ width="380" />
+ <icon
+ height="20"
+ follows="top|right|left"
+ image_name="ListItem_Select"
+ layout="topleft"
+ left="0"
+ name="landmark_icon"
+ top="0"
+ visible="false"
+ width="20" />
+ <text
+ follows="left|right"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ name="region"
+ text_color="white"
+ top="4"
+ value="Unknown"
+ width="380" />
+ <button
+ follows="right"
+ height="18"
+ image_disabled="Info"
+ image_disabled_selected="Info"
+ image_hover_selected="Info"
+ image_selected="Info"
+ image_unselected="Info"
+ layout="topleft"
+ name="info_btn"
+ picture_style="true"
+ visible="false"
+ right="-5"
+ top="2"
+ width="18" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 2eb9ba6d07..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>
@@ -1819,7 +1832,7 @@ this texture in your inventory
<string name="AnimFlagStart" value=" Start Animation : " />
<string name="Wave" value=" Wave " />
<string name="HelloAvatar" value=" Hello, avatar! " />
- <string name="ViewAllGestures" value=" View All >>" />
+ <string name="ViewAllGestures" value=" View All &gt;&gt;" />
<!-- inventory filter -->
<!-- use value="" because they have preceding spaces -->
diff --git a/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml
index eabacbecb2..df5ea24c73 100644
--- a/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml
+++ b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<accordion_tab
- header_collapse_img="accordion_collapsed.tga"
- header_collapse_img_pressed="accordion_collapsed.tga"
- header_expand_img="accordion_expanded.tga"
- header_expand_img_pressed="accordion_expanded.tga" />
+<accordion_tab
+ header_collapse_img="Accordion_ArrowClosed_Off"
+ header_collapse_img_pressed="Accordion_ArrowClosed_Press"
+ header_expand_img="Accordion_ArrowOpened_Off"
+ header_expand_img_pressed="Accordion_ArrowOpened_Press" />
diff --git a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml
new file mode 100644
index 0000000000..bcfc2f6472
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<expandable_text
+ max_height="300" >
+ <textbox
+ follows="left|top"
+ name="text"
+ use_ellipses="true"
+ word_wrap="true"
+ tab_stop="true"
+ v_pad="2"
+ h_pad="3" >
+ <expand_textbox
+ name="expand"
+ follows="bottom|right"
+ visible="false"
+ bg_visible="false"
+ tab_stop="false"
+ v_pad="0"
+ h_pad="0"
+ text="[http://www.DUMMY.com More]"
+ tool_tip="Click to expand text"/>
+ </textbox>
+ <scroll
+ name="scroll"
+ follows="all"
+ />
+</expandable_text> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
index ada258fbec..ec8395a7c5 100644
--- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
@@ -2,16 +2,16 @@
<filter_editor
clear_button_visible="true"
search_button_visible="true"
- text_pad_left="4"
+ text_pad_left="5"
select_on_focus="true"
background_image="TextField_Search_Off"
background_image_disabled="TextField_Search_Disabled"
- background_image_focused="TextField_Search_Active" >
+ background_image_focused="TextField_Search_Active">
<search_button label=""
top_pad="4"
- left_pad="4"
+ left_pad="4"
width="13"
- height="13"
+ height="13"
image_unselected="Search"
image_selected="Search" />
<clear_button label=""
diff --git a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
index 24d072a573..8078579806 100644
--- a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
+++ b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<flat_list_view
allow_select="true"
- item_pad="5"
+ color="DkGray2"
+ item_pad="0"
keep_one_selected="true"
multi_select="false"
opaque="true" /> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/list.xml b/indra/newview/skins/default/xui/en/widgets/list.xml
deleted file mode 100644
index 4a59716464..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/list.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<list
- allow_select="true"
- bg_opaque_color="PanelFocusBackgroundColor"
- bg_alpha_color="PanelDefaultBackgroundColor"
- background_visible="false"
- background_opaque="false"
- item_pad="5"
- keep_one_selected="true"
- multi_select="false" /> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml
index a37ed76c51..df8a9431d7 100644
--- a/indra/newview/skins/default/xui/en/widgets/location_input.xml
+++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml
@@ -44,7 +44,8 @@
label=""
pad_right="0"
tool_tip="My Location History"/>
- <combo_list bg_writeable_color="MenuDefaultBgColor" page_lines="10"/>
+ <combo_list bg_writeable_color="MenuDefaultBgColor" page_lines="10"
+ scroll_bar_bg_visible="true" />
<combo_editor name="Combo Text Entry"
text_pad_left="20"
select_on_focus="false"
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 e3a53eee4d..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,7 +10,9 @@
highlighted_color="ScrollHighlightedColor"
column_padding="5"
draw_stripes="true"
- background_visible="true"
- heading_height="20"
- draw_border="true"
- draw_heading="false"/>
+ scroll_bar_bg_visible="false"
+ scroll_bar_bg_color="black"
+ background_visible="false"
+ heading_height="23"
+ draw_border="false"
+ 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/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml
index 3e0f6513cc..071d505569 100644
--- a/indra/newview/skins/default/xui/es/floater_about.xml
+++ b/indra/newview/skins/default/xui/es/floater_about.xml
@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_about" title="Acerca de [APP_NAME]">
+<tab_container name="about_tab">
+ <panel name="credits_panel">
<text_editor name="credits_editor">
Le ofrecen Second Life Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl, y otros muchos.
Gracias a todos estos residentes por contribuir a garantizar que esta es la mejor versión: able whitman, Adeon Writer, adonaira aabye, Aeron Kohime, Agathos Frascati, Aimee Trescothick, Aleric Inglewood, Alissa Sabre, Aminom Marvin, Angela Talamasca, Aralara Rajal, Armin Weatherwax, Ashrilyn Hayashida, Athanasius Skytower, Aura Dirval, Barney Boomslang, Biancaluce Robbiani, Biker Offcourse, Borg Capalini, Bulli Schumann, catherine pfeffer, Chalice Yao, Corre Porta, Court Goodman, Cummere Mayo, Dale Innis, Darien Caldwell, Darjeeling Schoonhoven, Daten Thielt, dimentox travanti, Dirk Talamasca, Drew Dwi, Duckless Vandyke, Elanthius Flagstaff, Electro Burnstein, emiley tomsen, Escort DeFarge, Eva Rau, Ezian Ecksol, Fire Centaur, Fluf Fredriksson, Francisco Koolhoven, Frontera Thor, Frungi Stastny, Gally Young, gearsawe stonecutter, Gigs Taggart, Gordon Wendt, Gudmund Shepherd, Gypsy Paz, Harleen Gretzky, Henri Beauchamp, Inma Rau, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Jessicka Graves, Joeseph Albanese, Joshua Philgarlic, Khyota Wulluf, kirstenlee Cinquetti, Latif Khalifa, Lex Neva, Lilibeth Andree, Lisa Lowe, Lunita Savira, Loosey Demonia, lum pfohl, Marcos Fonzarelli, MartinRJ Fayray, Marusame Arai, Matthew Dowd, Maya Remblai, McCabe Maxsted, Meghan Dench, Melchoir Tokhes, Menos Short, Michelle2 Zenovka, Mimika Oh, Minerva Memel, Mm Alder, Ochi Wolfe, Omei Turnbull, Pesho Replacement, Phantom Ninetails, phoenixflames kukulcan, Polo Gufler, prez pessoa, princess niven, Prokofy Neva, Qie Niangao, Rem Beattie, RodneyLee Jessop, Saijanai Kuhn, Seg Baphomet, Sergen Davies, Shirley Marquez, SignpostMarv Martin, Sindy Tsure, Sira Arbizu, Skips Jigsaw, Sougent Harrop, Spritely Pixel, Squirrel Wood, StarSong Bright, Subversive Writer, Sugarcult Dagger, Sylumm Grigorovich, Tammy Nowotny, Tanooki Darkes, Tayra Dagostino, Theoretical Chemistry, Thickbrick Sleaford, valerie rosewood, Vex Streeter, Vixen Heron, Whoops Babii, Winter Ventura, Xiki Luik, Yann Dufaux, Yina Yao, Yukinoroh Kamachi, Zolute Infinity, Zwagoth Klaar
+
+
+ Para tener éxito en los negocios, se atrevido, se el primero, se diferente. (Henry Marchant)
+ </text_editor>
+ </panel>
+ <panel name="licenses_panel">
+ <text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
APR Copyright (C) 2000-2004 The Apache Software Foundation
cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
@@ -26,10 +35,9 @@
All rights reserved. See licenses.txt for details.
Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
-
-
- Para tener éxito en los negocios, se atrevido, se el primero, se diferente. (Henry Marchant)
</text_editor>
+ </panel>
+</tab_container>
<string name="you_are_at">
Está en [POSITION]
</string>
diff --git a/indra/newview/skins/default/xui/es/floater_map.xml b/indra/newview/skins/default/xui/es/floater_map.xml
index c167221b73..eee9caf830 100644
--- a/indra/newview/skins/default/xui/es/floater_map.xml
+++ b/indra/newview/skins/default/xui/es/floater_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Map">
- <floater.string name="mini_map_north">
- N
- </floater.string>
- <floater.string name="mini_map_east">
- E
- </floater.string>
- <floater.string name="mini_map_west">
- O
- </floater.string>
- <floater.string name="mini_map_south">
- S
- </floater.string>
- <floater.string name="mini_map_southeast">
- SE
- </floater.string>
- <floater.string name="mini_map_northeast">
- NE
- </floater.string>
- <floater.string name="mini_map_southwest">
- SO
- </floater.string>
- <floater.string name="mini_map_northwest">
- NO
- </floater.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="E" name="floater_map_east" text="E">
- E
- </text>
- <text label="O" name="floater_map_west" text="O">
- O
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SE" name="floater_map_southeast" text="SE">
- SE
- </text>
- <text label="NE" name="floater_map_northeast" text="NE">
- NE
- </text>
- <text label="SO" name="floater_map_southwest" text="SO">
- SO
- </text>
- <text label="NW" name="floater_map_northwest" text="NO">
- NO
- </text>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Map">
+ <floater.string name="mini_map_north">
+ N
+ </floater.string>
+ <floater.string name="mini_map_east">
+ E
+ </floater.string>
+ <floater.string name="mini_map_west">
+ O
+ </floater.string>
+ <floater.string name="mini_map_south">
+ S
+ </floater.string>
+ <floater.string name="mini_map_southeast">
+ SE
+ </floater.string>
+ <floater.string name="mini_map_northeast">
+ NE
+ </floater.string>
+ <floater.string name="mini_map_southwest">
+ SO
+ </floater.string>
+ <floater.string name="mini_map_northwest">
+ NO
+ </floater.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="E" name="floater_map_east" text="E">
+ E
+ </text>
+ <text label="O" name="floater_map_west" text="O">
+ O
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SE" name="floater_map_southeast" text="SE">
+ SE
+ </text>
+ <text label="NE" name="floater_map_northeast" text="NE">
+ NE
+ </text>
+ <text label="SO" name="floater_map_southwest" text="SO">
+ SO
+ </text>
+ <text label="NW" name="floater_map_northwest" text="NO">
+ NO
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
index 2718ead861..02fb4da017 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="advanced">
- <text name="AspectRatioLabel1" tool_tip="ancho / alto">
- Proporción:
- </text>
- <combo_box name="aspect_ratio" tool_tip="ancho / alto">
- <combo_box.item label="4:3 (Standard CRT)" name="item1"/>
- <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
- <combo_box.item label="8:5 (Widescreen)" name="item3"/>
- <combo_box.item label="16:9 (Widescreen)" name="item4"/>
- </combo_box>
-</panel>
+<?xml version="1.0" encoding="utf-8"?>
+<panel name="advanced">
+ <text name="AspectRatioLabel1" tool_tip="ancho / alto">
+ Proporción:
+ </text>
+ <combo_box name="aspect_ratio" tool_tip="ancho / alto">
+ <combo_box.item label="4:3 (Standard CRT)" name="item1"/>
+ <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
+ <combo_box.item label="8:5 (Widescreen)" name="item3"/>
+ <combo_box.item label="16:9 (Widescreen)" name="item4"/>
+ </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_world_map.xml b/indra/newview/skins/default/xui/es/panel_world_map.xml
index 93d0ea8fe3..7cb4009422 100644
--- a/indra/newview/skins/default/xui/es/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/es/panel_world_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="world_map">
- <panel.string name="world_map_north">
- N
- </panel.string>
- <panel.string name="world_map_east">
- E
- </panel.string>
- <panel.string name="world_map_west">
- O
- </panel.string>
- <panel.string name="world_map_south">
- S
- </panel.string>
- <panel.string name="world_map_southeast">
- SE
- </panel.string>
- <panel.string name="world_map_northeast">
- NE
- </panel.string>
- <panel.string name="world_map_southwest">
- SO
- </panel.string>
- <panel.string name="world_map_northwest">
- NO
- </panel.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="E" name="floater_map_east" text="E">
- E
- </text>
- <text label="O" name="floater_map_west" text="O">
- O
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SE" name="floater_map_southeast" text="SE">
- SE
- </text>
- <text label="NE" name="floater_map_northeast" text="NE">
- NE
- </text>
- <text label="SO" name="floater_map_southwest" text="SO">
- SO
- </text>
- <text label="NW" name="floater_map_northwest" text="NO">
- NO
- </text>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="world_map">
+ <panel.string name="world_map_north">
+ N
+ </panel.string>
+ <panel.string name="world_map_east">
+ E
+ </panel.string>
+ <panel.string name="world_map_west">
+ O
+ </panel.string>
+ <panel.string name="world_map_south">
+ S
+ </panel.string>
+ <panel.string name="world_map_southeast">
+ SE
+ </panel.string>
+ <panel.string name="world_map_northeast">
+ NE
+ </panel.string>
+ <panel.string name="world_map_southwest">
+ SO
+ </panel.string>
+ <panel.string name="world_map_northwest">
+ NO
+ </panel.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="E" name="floater_map_east" text="E">
+ E
+ </text>
+ <text label="O" name="floater_map_west" text="O">
+ O
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SE" name="floater_map_southeast" text="SE">
+ SE
+ </text>
+ <text label="NE" name="floater_map_northeast" text="NE">
+ NE
+ </text>
+ <text label="SO" name="floater_map_southwest" text="SO">
+ SO
+ </text>
+ <text label="NW" name="floater_map_northwest" text="NO">
+ NO
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml
index e05a6d1596..7b918be075 100644
--- a/indra/newview/skins/default/xui/fr/floater_about.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about.xml
@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_about" title="A propos de [APP_NAME]">
+<tab_container name="about_tab">
+ <panel name="credits_panel">
<text_editor name="credits_editor">
Second Life existe grâce aux efforts de Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl et de nombreuses autres personnes.
Tous nos remerciements aux résidents suivants pour avoir testé cette version (la meilleure qui soit jusqu&apos;à présent) : able whitman, Adeon Writer, adonaira aabye, Aeron Kohime, Agathos Frascati, Aimee Trescothick, Aleric Inglewood, Alissa Sabre, Aminom Marvin, Angela Talamasca, Aralara Rajal, Armin Weatherwax, Ashrilyn Hayashida, Athanasius Skytower, Aura Dirval, Barney Boomslang, Biancaluce Robbiani, Biker Offcourse, Borg Capalini, Bulli Schumann, catherine pfeffer, Chalice Yao, Corre Porta, Court Goodman, Cummere Mayo, Dale Innis, Darien Caldwell, Darjeeling Schoonhoven, Daten Thielt, dimentox travanti, Dirk Talamasca, Drew Dwi, Duckless Vandyke, Elanthius Flagstaff, Electro Burnstein, emiley tomsen, Escort DeFarge, Eva Rau, Ezian Ecksol, Fire Centaur, Fluf Fredriksson, Francisco Koolhoven, Frontera Thor, Frungi Stastny, Gally Young, gearsawe stonecutter, Gigs Taggart, Gordon Wendt, Gudmund Shepherd, Gypsy Paz, Harleen Gretzky, Henri Beauchamp, Inma Rau, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Jessicka Graves, Joeseph Albanese, Joshua Philgarlic, Khyota Wulluf, kirstenlee Cinquetti, Latif Khalifa, Lex Neva, Lilibeth Andree, Lisa Lowe, Lunita Savira, Loosey Demonia, lum pfohl, Marcos Fonzarelli, MartinRJ Fayray, Marusame Arai, Matthew Dowd, Maya Remblai, McCabe Maxsted, Meghan Dench, Melchoir Tokhes, Menos Short, Michelle2 Zenovka, Mimika Oh, Minerva Memel, Mm Alder, Ochi Wolfe, Omei Turnbull, Pesho Replacement, Phantom Ninetails, phoenixflames kukulcan, Polo Gufler, prez pessoa, princess niven, Prokofy Neva, Qie Niangao, Rem Beattie, RodneyLee Jessop, Saijanai Kuhn, Seg Baphomet, Sergen Davies, Shirley Marquez, SignpostMarv Martin, Sindy Tsure, Sira Arbizu, Skips Jigsaw, Sougent Harrop, Spritely Pixel, Squirrel Wood, StarSong Bright, Subversive Writer, Sugarcult Dagger, Sylumm Grigorovich, Tammy Nowotny, Tanooki Darkes, Tayra Dagostino, Theoretical Chemistry, Thickbrick Sleaford, valerie rosewood, Vex Streeter, Vixen Heron, Whoops Babii, Winter Ventura, Xiki Luik, Yann Dufaux, Yina Yao, Yukinoroh Kamachi, Zolute Infinity, Zwagoth Klaar
+
+
+ Pour réussir dans les affaires, soyez audacieux, créatif et différent. - Henry Marchant
+ </text_editor>
+ </panel>
+ <panel name="licenses_panel">
+ <text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
APR Copyright (C) 2000-2004 The Apache Software Foundation
cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
@@ -25,10 +34,9 @@
Tous droits réservés. Voir licenses.txt pour plus de détails.
Codage Audio du chat vocal : Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
-
-
- Pour réussir dans les affaires, soyez audacieux, créatif et différent. - Henry Marchant
</text_editor>
+ </panel>
+</tab_container>
<string name="you_are_at">
Votre position : [POSITION]
</string>
diff --git a/indra/newview/skins/default/xui/fr/floater_map.xml b/indra/newview/skins/default/xui/fr/floater_map.xml
index 20bd9e60b4..ec4bd4ef4a 100644
--- a/indra/newview/skins/default/xui/fr/floater_map.xml
+++ b/indra/newview/skins/default/xui/fr/floater_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Map">
- <floater.string name="mini_map_north">
- N
- </floater.string>
- <floater.string name="mini_map_east">
- E
- </floater.string>
- <floater.string name="mini_map_west">
- O
- </floater.string>
- <floater.string name="mini_map_south">
- S
- </floater.string>
- <floater.string name="mini_map_southeast">
- SE
- </floater.string>
- <floater.string name="mini_map_northeast">
- NE
- </floater.string>
- <floater.string name="mini_map_southwest">
- SO
- </floater.string>
- <floater.string name="mini_map_northwest">
- NO
- </floater.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="E" name="floater_map_east" text="E">
- E
- </text>
- <text label="O" name="floater_map_west" text="O">
- O
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SE" name="floater_map_southeast" text="SE">
- SE
- </text>
- <text label="NE" name="floater_map_northeast" text="NE">
- NE
- </text>
- <text label="SO" name="floater_map_southwest" text="SO">
- SO
- </text>
- <text label="NO" name="floater_map_northwest" text="NO">
- NO
- </text>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Map">
+ <floater.string name="mini_map_north">
+ N
+ </floater.string>
+ <floater.string name="mini_map_east">
+ E
+ </floater.string>
+ <floater.string name="mini_map_west">
+ O
+ </floater.string>
+ <floater.string name="mini_map_south">
+ S
+ </floater.string>
+ <floater.string name="mini_map_southeast">
+ SE
+ </floater.string>
+ <floater.string name="mini_map_northeast">
+ NE
+ </floater.string>
+ <floater.string name="mini_map_southwest">
+ SO
+ </floater.string>
+ <floater.string name="mini_map_northwest">
+ NO
+ </floater.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="E" name="floater_map_east" text="E">
+ E
+ </text>
+ <text label="O" name="floater_map_west" text="O">
+ O
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SE" name="floater_map_southeast" text="SE">
+ SE
+ </text>
+ <text label="NE" name="floater_map_northeast" text="NE">
+ NE
+ </text>
+ <text label="SO" name="floater_map_southwest" text="SO">
+ SO
+ </text>
+ <text label="NO" name="floater_map_northwest" text="NO">
+ NO
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml
index 89b4096de7..4f0f6a8a23 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="advanced">
- <text name="AspectRatioLabel1" tool_tip="largeur/hauteur">
- Rapport hauteur/largeur :
- </text>
- <combo_box name="aspect_ratio" tool_tip="largeur/hauteur">
- <combo_box.item label="4:3 (Standard CRT)" name="item1"/>
- <combo_box.item label="5:4 (1280 x 1024 LCD)" name="item2"/>
- <combo_box.item label="8:5 (écran large)" name="item3"/>
- <combo_box.item label="16:9 (plein écran)" name="item4"/>
- </combo_box>
-</panel>
+<?xml version="1.0" encoding="utf-8"?>
+<panel name="advanced">
+ <text name="AspectRatioLabel1" tool_tip="largeur/hauteur">
+ Rapport hauteur/largeur :
+ </text>
+ <combo_box name="aspect_ratio" tool_tip="largeur/hauteur">
+ <combo_box.item label="4:3 (Standard CRT)" name="item1"/>
+ <combo_box.item label="5:4 (1280 x 1024 LCD)" name="item2"/>
+ <combo_box.item label="8:5 (écran large)" name="item3"/>
+ <combo_box.item label="16:9 (plein écran)" name="item4"/>
+ </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_world_map.xml b/indra/newview/skins/default/xui/fr/panel_world_map.xml
index 4d4f94273b..d00157a297 100644
--- a/indra/newview/skins/default/xui/fr/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/fr/panel_world_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="world_map">
- <panel.string name="world_map_north">
- N
- </panel.string>
- <panel.string name="world_map_east">
- E
- </panel.string>
- <panel.string name="world_map_west">
- O
- </panel.string>
- <panel.string name="world_map_south">
- S
- </panel.string>
- <panel.string name="world_map_southeast">
- SE
- </panel.string>
- <panel.string name="world_map_northeast">
- NE
- </panel.string>
- <panel.string name="world_map_southwest">
- SO
- </panel.string>
- <panel.string name="world_map_northwest">
- NO
- </panel.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="E" name="floater_map_east" text="E">
- E
- </text>
- <text label="O" name="floater_map_west" text="O">
- O
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SE" name="floater_map_southeast" text="SE">
- SE
- </text>
- <text label="NE" name="floater_map_northeast" text="NE">
- NE
- </text>
- <text label="SO" name="floater_map_southwest" text="SO">
- SO
- </text>
- <text label="NO" name="floater_map_northwest" text="NO">
- NO
- </text>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="world_map">
+ <panel.string name="world_map_north">
+ N
+ </panel.string>
+ <panel.string name="world_map_east">
+ E
+ </panel.string>
+ <panel.string name="world_map_west">
+ O
+ </panel.string>
+ <panel.string name="world_map_south">
+ S
+ </panel.string>
+ <panel.string name="world_map_southeast">
+ SE
+ </panel.string>
+ <panel.string name="world_map_northeast">
+ NE
+ </panel.string>
+ <panel.string name="world_map_southwest">
+ SO
+ </panel.string>
+ <panel.string name="world_map_northwest">
+ NO
+ </panel.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="E" name="floater_map_east" text="E">
+ E
+ </text>
+ <text label="O" name="floater_map_west" text="O">
+ O
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SE" name="floater_map_southeast" text="SE">
+ SE
+ </text>
+ <text label="NE" name="floater_map_northeast" text="NE">
+ NE
+ </text>
+ <text label="SO" name="floater_map_southwest" text="SO">
+ SO
+ </text>
+ <text label="NO" name="floater_map_northwest" text="NO">
+ NO
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml
index 597208eedb..2c91375930 100644
--- a/indra/newview/skins/default/xui/it/floater_about.xml
+++ b/indra/newview/skins/default/xui/it/floater_about.xml
@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_about" title="Informazioni su [APP_NAME]">
+<tab_container name="about_tab">
+ <panel name="credits_panel">
<text_editor name="credits_editor">
Second Life è offerto da Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl and many others.
Si ringraziano i seguenti residenti per aver contribuito a rendere questa versione la migliore possibile: able whitman, Adeon Writer, adonaira aabye, Aeron Kohime, Agathos Frascati, Aimee Trescothick, Aleric Inglewood, Alissa Sabre, Aminom Marvin, Angela Talamasca, Aralara Rajal, Armin Weatherwax, Ashrilyn Hayashida, Athanasius Skytower, Aura Dirval, Barney Boomslang, Biancaluce Robbiani, Biker Offcourse, Borg Capalini, Bulli Schumann, catherine pfeffer, Chalice Yao, Corre Porta, Court Goodman, Cummere Mayo, Dale Innis, Darien Caldwell, Darjeeling Schoonhoven, Daten Thielt, dimentox travanti, Dirk Talamasca, Drew Dwi, Duckless Vandyke, Elanthius Flagstaff, Electro Burnstein, emiley tomsen, Escort DeFarge, Eva Rau, Ezian Ecksol, Fire Centaur, Fluf Fredriksson, Francisco Koolhoven, Frontera Thor, Frungi Stastny, Gally Young, gearsawe stonecutter, Gigs Taggart, Gordon Wendt, Gudmund Shepherd, Gypsy Paz, Harleen Gretzky, Henri Beauchamp, Inma Rau, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Jessicka Graves, Joeseph Albanese, Joshua Philgarlic, Khyota Wulluf, kirstenlee Cinquetti, Latif Khalifa, Lex Neva, Lilibeth Andree, Lisa Lowe, Lunita Savira, Loosey Demonia, lum pfohl, Marcos Fonzarelli, MartinRJ Fayray, Marusame Arai, Matthew Dowd, Maya Remblai, McCabe Maxsted, Meghan Dench, Melchoir Tokhes, Menos Short, Michelle2 Zenovka, Mimika Oh, Minerva Memel, Mm Alder, Ochi Wolfe, Omei Turnbull, Pesho Replacement, Phantom Ninetails, phoenixflames kukulcan, Polo Gufler, prez pessoa, princess niven, Prokofy Neva, Qie Niangao, Rem Beattie, RodneyLee Jessop, Saijanai Kuhn, Seg Baphomet, Sergen Davies, Shirley Marquez, SignpostMarv Martin, Sindy Tsure, Sira Arbizu, Skips Jigsaw, Sougent Harrop, Spritely Pixel, Squirrel Wood, StarSong Bright, Subversive Writer, Sugarcult Dagger, Sylumm Grigorovich, Tammy Nowotny, Tanooki Darkes, Tayra Dagostino, Theoretical Chemistry, Thickbrick Sleaford, valerie rosewood, Vex Streeter, Vixen Heron, Whoops Babii, Winter Ventura, Xiki Luik, Yann Dufaux, Yina Yao, Yukinoroh Kamachi, Zolute Infinity, Zwagoth Klaar
+
+
+ Per avere successo nel business, sii coraggioso, sii il primo, sii differente. --Henry Marchant
+ </text_editor>
+ </panel>
+ <panel name="licenses_panel">
+ <text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
APR Copyright (C) 2000-2004 The Apache Software Foundation
cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
@@ -26,10 +35,9 @@
Tutti i diritti riservati. Leggi licenses.txt per maggiori dettagli.
Chat vocale Codifica audio: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
-
-
- Per avere successo nel business, sii coraggioso, sii il primo, sii differente. --Henry Marchant
</text_editor>
+ </panel>
+</tab_container>
<string name="you_are_at">
Sei a [POSITION]
</string>
diff --git a/indra/newview/skins/default/xui/it/floater_map.xml b/indra/newview/skins/default/xui/it/floater_map.xml
index 20bd9e60b4..ec4bd4ef4a 100644
--- a/indra/newview/skins/default/xui/it/floater_map.xml
+++ b/indra/newview/skins/default/xui/it/floater_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Map">
- <floater.string name="mini_map_north">
- N
- </floater.string>
- <floater.string name="mini_map_east">
- E
- </floater.string>
- <floater.string name="mini_map_west">
- O
- </floater.string>
- <floater.string name="mini_map_south">
- S
- </floater.string>
- <floater.string name="mini_map_southeast">
- SE
- </floater.string>
- <floater.string name="mini_map_northeast">
- NE
- </floater.string>
- <floater.string name="mini_map_southwest">
- SO
- </floater.string>
- <floater.string name="mini_map_northwest">
- NO
- </floater.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="E" name="floater_map_east" text="E">
- E
- </text>
- <text label="O" name="floater_map_west" text="O">
- O
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SE" name="floater_map_southeast" text="SE">
- SE
- </text>
- <text label="NE" name="floater_map_northeast" text="NE">
- NE
- </text>
- <text label="SO" name="floater_map_southwest" text="SO">
- SO
- </text>
- <text label="NO" name="floater_map_northwest" text="NO">
- NO
- </text>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Map">
+ <floater.string name="mini_map_north">
+ N
+ </floater.string>
+ <floater.string name="mini_map_east">
+ E
+ </floater.string>
+ <floater.string name="mini_map_west">
+ O
+ </floater.string>
+ <floater.string name="mini_map_south">
+ S
+ </floater.string>
+ <floater.string name="mini_map_southeast">
+ SE
+ </floater.string>
+ <floater.string name="mini_map_northeast">
+ NE
+ </floater.string>
+ <floater.string name="mini_map_southwest">
+ SO
+ </floater.string>
+ <floater.string name="mini_map_northwest">
+ NO
+ </floater.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="E" name="floater_map_east" text="E">
+ E
+ </text>
+ <text label="O" name="floater_map_west" text="O">
+ O
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SE" name="floater_map_southeast" text="SE">
+ SE
+ </text>
+ <text label="NE" name="floater_map_northeast" text="NE">
+ NE
+ </text>
+ <text label="SO" name="floater_map_southwest" text="SO">
+ SO
+ </text>
+ <text label="NO" name="floater_map_northwest" text="NO">
+ NO
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml
index cf1e22997a..2355dc7f0a 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="advanced">
- <text name="AspectRatioLabel1" tool_tip="larghezza/altezza">
- Rapporto di visualizzazione:
- </text>
- <combo_box name="aspect_ratio" tool_tip="larghezza/altezza">
- <combo_box.item label="4:3 (Monitor Standard)" name="item1"/>
- <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
- <combo_box.item label="8:5 (Widescreen)" name="item3"/>
- <combo_box.item label="16:9 (Widescreen)" name="item4"/>
- </combo_box>
-</panel>
+<?xml version="1.0" encoding="utf-8"?>
+<panel name="advanced">
+ <text name="AspectRatioLabel1" tool_tip="larghezza/altezza">
+ Rapporto di visualizzazione:
+ </text>
+ <combo_box name="aspect_ratio" tool_tip="larghezza/altezza">
+ <combo_box.item label="4:3 (Monitor Standard)" name="item1"/>
+ <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
+ <combo_box.item label="8:5 (Widescreen)" name="item3"/>
+ <combo_box.item label="16:9 (Widescreen)" name="item4"/>
+ </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_world_map.xml b/indra/newview/skins/default/xui/it/panel_world_map.xml
index 4d4f94273b..d00157a297 100644
--- a/indra/newview/skins/default/xui/it/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/it/panel_world_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="world_map">
- <panel.string name="world_map_north">
- N
- </panel.string>
- <panel.string name="world_map_east">
- E
- </panel.string>
- <panel.string name="world_map_west">
- O
- </panel.string>
- <panel.string name="world_map_south">
- S
- </panel.string>
- <panel.string name="world_map_southeast">
- SE
- </panel.string>
- <panel.string name="world_map_northeast">
- NE
- </panel.string>
- <panel.string name="world_map_southwest">
- SO
- </panel.string>
- <panel.string name="world_map_northwest">
- NO
- </panel.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="E" name="floater_map_east" text="E">
- E
- </text>
- <text label="O" name="floater_map_west" text="O">
- O
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SE" name="floater_map_southeast" text="SE">
- SE
- </text>
- <text label="NE" name="floater_map_northeast" text="NE">
- NE
- </text>
- <text label="SO" name="floater_map_southwest" text="SO">
- SO
- </text>
- <text label="NO" name="floater_map_northwest" text="NO">
- NO
- </text>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="world_map">
+ <panel.string name="world_map_north">
+ N
+ </panel.string>
+ <panel.string name="world_map_east">
+ E
+ </panel.string>
+ <panel.string name="world_map_west">
+ O
+ </panel.string>
+ <panel.string name="world_map_south">
+ S
+ </panel.string>
+ <panel.string name="world_map_southeast">
+ SE
+ </panel.string>
+ <panel.string name="world_map_northeast">
+ NE
+ </panel.string>
+ <panel.string name="world_map_southwest">
+ SO
+ </panel.string>
+ <panel.string name="world_map_northwest">
+ NO
+ </panel.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="E" name="floater_map_east" text="E">
+ E
+ </text>
+ <text label="O" name="floater_map_west" text="O">
+ O
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SE" name="floater_map_southeast" text="SE">
+ SE
+ </text>
+ <text label="NE" name="floater_map_northeast" text="NE">
+ NE
+ </text>
+ <text label="SO" name="floater_map_southwest" text="SO">
+ SO
+ </text>
+ <text label="NO" name="floater_map_northwest" text="NO">
+ NO
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml
index fb12e48c9a..a9b3d81a3b 100644
--- a/indra/newview/skins/default/xui/ja/floater_about.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about.xml
@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="floater_about" title="[APP_NAME]について">
+<tab_container name="about_tab">
+ <panel name="credits_panel">
<text_editor name="credits_editor">
Second Lifeは、 Philip、Tessa、Andrew、Cory、James、Ben、Char、Charlie、Colin、Dan、Daniel、Doug、Eric、Hamlet、Haney、Eve、Hunter、Ian、Jeff、Jennifer、Jim、John、Lee、Mark、Peter、Phoenix、Richard、Robin、Xenon、Steve、Tanya、Eddie、Avi、Frank、Bruce、Aaron、Alice、Bob、Debra、Eileen、Helen、Janet、Louie、Leviathania、Stefan、Ray、Kevin、Tom、Mikeb、MikeT、Burgess、Elena、Tracy、Bill、Todd、Ryan、Zach、Sarah、Nova、Tim、Stephanie、Michael、Evan、Nicolas、Catherine、Rachelle、Dave、Holly、Bub、Kelly、Magellan、Ramzi、Don、Sabin、Jill、Rheya、Jeska、Torley、Kona、Callum、Charity、Ventrella、Jack、Vektor、Iris、Chris、Nicole、Mick、Reuben、Blue、Babbage、Yedwab、Deana、Lauren、Brent、Pathfinder、Chadrick、Altruima、Jesse、Teeny、Monroe、Icculus、David、Tess、Lizzie、Patsy、Isaac、Lawrence、Cyn、Bo、Gia、Annette、Marius、Tbone、Jonathan、Karen、Ginsu、Satoko、Yuko、Makiko、Thomas、Harry、Seth、Alexei、Brian、Guy、Runitai、Ethan、Data、Cornelius、Kenny、Swiss、Zero、Natria、Wendy、Stephen、Teeple、Thumper、Lucy、Dee、Mia、Liana、Warren、Branka、Aura、beez、Milo、Hermia、Red、Thrax、Joe、Sally、Magenta、Mogura、Paul、Jose、Rejean、Henrik、Lexie、Amber、Logan、Xan、Nora、Morpheus、Donovan、Leyla、MichaelFrancis、Beast、Cube、Bucky、Joshua、Stryfe、Harmony、Teresa、Claudia、Walker、Glenn、Fritz、Fordak、June、Cleopetra、Jean、Ivy、Betsy、Roosevelt、Spike、Ken、Which、Tofu、Chiyo、Rob、Zee、dustin、George、Del、Matthew、Cat、Jacqui、Lightfoot、Adrian、Viola、Alfred、Noel、Irfan、Sunil、Yool、Rika、Jane、Xtreme、Frontier、a2、Neo、Siobhan、Yoz、Justin、Elle、Qarl、Benjamin、Isabel、Gulliver、Everett、Christopher、Izzy、Stephany、Garry、Sejong、Sean、Tobin、Iridium、Meta、Anthony、Jeremy、JP、Jake、Maurice、Madhavi、Leopard、Kyle、Joon、Kari、Bert、Belinda、Jon、Kristi、Bridie、Pramod、KJ、Socrates、Maria、Ivan、Aric、Yamasaki、Adreanne、Jay、MitchK、Ceren、Coco、Durl、Jenny、Periapse、Kartic、Storrs、Lotte、Sandy、Rohn、Colossus、Zen、BigPapi、Brad、Pastrami、Kurz、Mani、Neuro、Jaime、MJ、Rowan、Sgt、Elvis、Gecko、Samuel、Sardonyx、Leo、Bryan、Niko、Soft、Poppy、Rachel、Aki、Angelo、Banzai、Alexa、Sue、CeeLo、Bender、CG、Gillian、Pelle、Nick、Echo、Zara、Christine、Shamiran、Emma、Blake、Keiko、Plexus、Joppa、Sidewinder、Erica、Ashlei、Twilight、Kristen、Brett、Q、Enus、Simon、Bevis、Kraft、Kip、Chandler、Ron、LauraP、Ram、KyleJM、Scouse、Prospero、Melissa、Marty、Nat、Hamilton、Kend、Lordan、Jimmy、Kosmo、Seraph、Green、Ekim、Wiggo、JT、Rome、Doris、Miz、Benoc、Whump、Trinity、Patch、Kate、TJ、Bao、Joohwan、Christy、Sofia、Matias、Cogsworth、Johan、Oreh、Cheah、Angela、Brandy、Mango、Lan、Aleks、Gloria、Heidy、Mitchell、Space、Colton、Bambers、Einstein、Maggie、Malbers、Rose、Winnie、Stella、Milton、Rothman、Niall、Marin、Allison、Katie、Dawn、Katt、Dusty、Kalpana、Judy、Andrea、Ambroff、Infinity、Gail、Rico、Raymond、Yi、William、Christa、M、Teagan、Scout、Molly、Dante、Corr、Dynamike、Usi、Kaylee、Vidtuts、Lil、Danica、Sascha、Kelv、Jacob、Nya、Rodney、Brandon、Elsie、Blondin、Grant、Katrin、Nyx、Gabriel、Locklainn、Claire、Devin、Minerva、Monty、Austin、Bradford、Si、Keira、H、Caitlin、Dita、Makai、Jenn、Ann、Meredith、Clare、Joy、Praveen、Cody、Edmund、Ruthe、Sirena、Gayathri、Spider、FJ、Davidoff、Tian、Jennie、Louise、Oskar、Landon、Noelle、Jarv、Ingrid、Al、Sommer、Doc、Aria、Huin、Gray、Lili、Vir、DJ、Yang、T、Simone、Maestro、Scott、Charlene、Quixote、Amanda、Susan、Zed、Anne、Enkidu、Esbee、Joroan、Katelin、Roxie、Tay、Scarlet、Kevin、Johnny、Wolfgang、Andren、Bob、Howard、Merov、Rand、Ray、Michon、Newell、Galen、Dessie、Les、Michon、Jenelle、Geo、Siz、Shapiro、Pete、Calyle、Selene、Allen、Phoebe、Goldin、Kimmora、Dakota、Slaton、Lindquist、Zoey、Hari、Othello、Rohit、Sheldon、Petra、Viale、Gordon、Kaye、Pink、Ferny、Emerson、Davy、Bri、Chan、Juan、Robert、Terrence、Nathan、Carlと、その他多数の人達によって作成されました。
このバージョンをこれまでで最高のものになるようご協力をいただいた以下の住人の皆様に深く感謝いたします。 able whitman, Adeon Writer, adonaira aabye, Aeron Kohime, Agathos Frascati, Aimee Trescothick, Aleric Inglewood, Alissa Sabre, Aminom Marvin, Angela Talamasca, Aralara Rajal, Armin Weatherwax, Ashrilyn Hayashida, Athanasius Skytower, Aura Dirval, Barney Boomslang, Biancaluce Robbiani, Biker Offcourse, Borg Capalini, Bulli Schumann, catherine pfeffer, Chalice Yao, Corre Porta, Court Goodman, Cummere Mayo, Dale Innis, Darien Caldwell, Darjeeling Schoonhoven, Daten Thielt, dimentox travanti, Dirk Talamasca, Drew Dwi, Duckless Vandyke, Elanthius Flagstaff, Electro Burnstein, emiley tomsen, Escort DeFarge, Eva Rau, Ezian Ecksol, Fire Centaur, Fluf Fredriksson, Francisco Koolhoven, Frontera Thor, Frungi Stastny, Gally Young, gearsawe stonecutter, Gigs Taggart, Gordon Wendt, Gudmund Shepherd, Gypsy Paz, Harleen Gretzky, Henri Beauchamp, Inma Rau, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Jessicka Graves, Joeseph Albanese, Joshua Philgarlic, Khyota Wulluf, kirstenlee Cinquetti, Latif Khalifa, Lex Neva, Lilibeth Andree, Lisa Lowe, Lunita Savira, Loosey Demonia, lum pfohl, Marcos Fonzarelli, MartinRJ Fayray, Marusame Arai, Matthew Dowd, Maya Remblai, McCabe Maxsted, Meghan Dench, Melchoir Tokhes, Menos Short, Michelle2 Zenovka, Mimika Oh, Minerva Memel, Mm Alder, Ochi Wolfe, Omei Turnbull, Pesho Replacement, Phantom Ninetails, phoenixflames kukulcan, Polo Gufler, prez pessoa, princess niven, Prokofy Neva, Qie Niangao, Rem Beattie, RodneyLee Jessop, Saijanai Kuhn, Seg Baphomet, Sergen Davies, Shirley Marquez, SignpostMarv Martin, Sindy Tsure, Sira Arbizu, Skips Jigsaw, Sougent Harrop, Spritely Pixel, Squirrel Wood, StarSong Bright, Subversive Writer, Sugarcult Dagger, Sylumm Grigorovich, Tammy Nowotny, Tanooki Darkes, Tayra Dagostino, Theoretical Chemistry, Thickbrick Sleaford, valerie rosewood, Vex Streeter, Vixen Heron, Whoops Babii, Winter Ventura, Xiki Luik, Yann Dufaux, Yina Yao, Yukinoroh Kamachi, Zolute Infinity, Zwagoth Klaar
+
+
+ ビジネスで成功するには、勇気を持って、誰よりも先に、人と違ったことをすることだ。 --Henry Marchant
+ </text_editor>
+ </panel>
+ <panel name="licenses_panel">
+ <text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
APR Copyright (C) 2000-2004 The Apache Software Foundation
cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
@@ -25,10 +34,9 @@
無断転写、複製、転載を禁じます。 詳細はlicenses.txtを参照してください。
Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
-
-
- ビジネスで成功するには、勇気を持って、誰よりも先に、人と違ったことをすることだ。 --Henry Marchant
</text_editor>
+ </panel>
+</tab_container>
<text name="you_are_at">
[POSITION]
</text>
diff --git a/indra/newview/skins/default/xui/ja/floater_map.xml b/indra/newview/skins/default/xui/ja/floater_map.xml
index 3884333c91..3356d4948a 100644
--- a/indra/newview/skins/default/xui/ja/floater_map.xml
+++ b/indra/newview/skins/default/xui/ja/floater_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Map">
- <floater.string name="mini_map_north">
- 北
- </floater.string>
- <floater.string name="mini_map_east">
- 東
- </floater.string>
- <floater.string name="mini_map_west">
- 西
- </floater.string>
- <floater.string name="mini_map_south">
- 南
- </floater.string>
- <floater.string name="mini_map_southeast">
- 南東
- </floater.string>
- <floater.string name="mini_map_northeast">
- 北東
- </floater.string>
- <floater.string name="mini_map_southwest">
- 南西
- </floater.string>
- <floater.string name="mini_map_northwest">
- 北西
- </floater.string>
- <text label="北" name="floater_map_north" text="北">
- 北
- </text>
- <text label="東" name="floater_map_east" text="東">
- 東
- </text>
- <text label="西" name="floater_map_west" text="西">
- 西
- </text>
- <text label="南" name="floater_map_south" text="南">
- 南
- </text>
- <text label="南東" name="floater_map_southeast" text="南東">
- 南東
- </text>
- <text label="北東" name="floater_map_northeast" text="北東">
- 北東
- </text>
- <text label="南西" name="floater_map_southwest" text="南西">
- 南西
- </text>
- <text label="北西" name="floater_map_northwest" text="北西">
- 北西
- </text>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Map">
+ <floater.string name="mini_map_north">
+ 北
+ </floater.string>
+ <floater.string name="mini_map_east">
+ 東
+ </floater.string>
+ <floater.string name="mini_map_west">
+ 西
+ </floater.string>
+ <floater.string name="mini_map_south">
+ 南
+ </floater.string>
+ <floater.string name="mini_map_southeast">
+ 南東
+ </floater.string>
+ <floater.string name="mini_map_northeast">
+ 北東
+ </floater.string>
+ <floater.string name="mini_map_southwest">
+ 南西
+ </floater.string>
+ <floater.string name="mini_map_northwest">
+ 北西
+ </floater.string>
+ <text label="北" name="floater_map_north" text="北">
+ 北
+ </text>
+ <text label="東" name="floater_map_east" text="東">
+ 東
+ </text>
+ <text label="西" name="floater_map_west" text="西">
+ 西
+ </text>
+ <text label="南" name="floater_map_south" text="南">
+ 南
+ </text>
+ <text label="南東" name="floater_map_southeast" text="南東">
+ 南東
+ </text>
+ <text label="北東" name="floater_map_northeast" text="北東">
+ 北東
+ </text>
+ <text label="南西" name="floater_map_southwest" text="南西">
+ 南西
+ </text>
+ <text label="北西" name="floater_map_northwest" text="北西">
+ 北西
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml
index 4b6f1f061b..0665dd4590 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="advanced">
- <text name="AspectRatioLabel1" tool_tip="(幅/高さ)">
- 縦横比:
- </text>
- <combo_box name="aspect_ratio" tool_tip="(幅/高さ)">
- <combo_box.item label="4:3(標準CRT)" name="item1"/>
- <combo_box.item label="5:4(1280x1024 LCD)" name="item2"/>
- <combo_box.item label="8:5(ワイドスクリ-ン)" name="item3"/>
- <combo_box.item label="16:9(ワイドスクリ-ン)" name="item4"/>
- </combo_box>
-</panel>
+<?xml version="1.0" encoding="utf-8"?>
+<panel name="advanced">
+ <text name="AspectRatioLabel1" tool_tip="(幅/高さ)">
+ 縦横比:
+ </text>
+ <combo_box name="aspect_ratio" tool_tip="(幅/高さ)">
+ <combo_box.item label="4:3(標準CRT)" name="item1"/>
+ <combo_box.item label="5:4(1280x1024 LCD)" name="item2"/>
+ <combo_box.item label="8:5(ワイドスクリ-ン)" name="item3"/>
+ <combo_box.item label="16:9(ワイドスクリ-ン)" name="item4"/>
+ </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_world_map.xml b/indra/newview/skins/default/xui/ja/panel_world_map.xml
index 22b9471533..391379b072 100644
--- a/indra/newview/skins/default/xui/ja/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/ja/panel_world_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="world_map">
- <panel.string name="world_map_north">
- 北
- </panel.string>
- <panel.string name="world_map_east">
- 東
- </panel.string>
- <panel.string name="world_map_west">
- 西
- </panel.string>
- <panel.string name="world_map_south">
- 南
- </panel.string>
- <panel.string name="world_map_southeast">
- 南東
- </panel.string>
- <panel.string name="world_map_northeast">
- 北東
- </panel.string>
- <panel.string name="world_map_southwest">
- 南西
- </panel.string>
- <panel.string name="world_map_northwest">
- 北西
- </panel.string>
- <text label="北" name="floater_map_north" text="北">
- 北
- </text>
- <text label="東" name="floater_map_east" text="東">
- 東
- </text>
- <text label="西" name="floater_map_west" text="西">
- 西
- </text>
- <text label="南" name="floater_map_south" text="南">
- 南
- </text>
- <text label="南東" name="floater_map_southeast" text="南東">
- 南東
- </text>
- <text label="北東" name="floater_map_northeast" text="北東">
- 北東
- </text>
- <text label="南西" name="floater_map_southwest" text="南西">
- 南西
- </text>
- <text label="北西" name="floater_map_northwest" text="北西">
- 北西
- </text>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="world_map">
+ <panel.string name="world_map_north">
+ 北
+ </panel.string>
+ <panel.string name="world_map_east">
+ 東
+ </panel.string>
+ <panel.string name="world_map_west">
+ 西
+ </panel.string>
+ <panel.string name="world_map_south">
+ 南
+ </panel.string>
+ <panel.string name="world_map_southeast">
+ 南東
+ </panel.string>
+ <panel.string name="world_map_northeast">
+ 北東
+ </panel.string>
+ <panel.string name="world_map_southwest">
+ 南西
+ </panel.string>
+ <panel.string name="world_map_northwest">
+ 北西
+ </panel.string>
+ <text label="北" name="floater_map_north" text="北">
+ 北
+ </text>
+ <text label="東" name="floater_map_east" text="東">
+ 東
+ </text>
+ <text label="西" name="floater_map_west" text="西">
+ 西
+ </text>
+ <text label="南" name="floater_map_south" text="南">
+ 南
+ </text>
+ <text label="南東" name="floater_map_southeast" text="南東">
+ 南東
+ </text>
+ <text label="北東" name="floater_map_northeast" text="北東">
+ 北東
+ </text>
+ <text label="南西" name="floater_map_southwest" text="南西">
+ 南西
+ </text>
+ <text label="北西" name="floater_map_northwest" text="北西">
+ 北西
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/nl/floater_about.xml b/indra/newview/skins/default/xui/nl/floater_about.xml
index 4d5d8b1032..9ad947df66 100644
--- a/indra/newview/skins/default/xui/nl/floater_about.xml
+++ b/indra/newview/skins/default/xui/nl/floater_about.xml
@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_about" title="Over [APP_NAME]">
+<tab_container name="about_tab">
+ <panel name="credits_panel">
<text_editor name="credits_editor">
Second Life wordt u aangeboden door Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl and many others.
Een &apos;Dank u&apos; voor de volgende bewoners voor het helpen zorgdragen dat dit de beste versie tot nu toe is: able whitman, Adeon Writer, adonaira aabye, Aeron Kohime, Agathos Frascati, Aimee Trescothick, Aleric Inglewood, Alissa Sabre, Aminom Marvin, Angela Talamasca, Aralara Rajal, Armin Weatherwax, Ashrilyn Hayashida, Athanasius Skytower, Aura Dirval, Barney Boomslang, Biancaluce Robbiani, Biker Offcourse, Borg Capalini, Bulli Schumann, catherine pfeffer, Chalice Yao, Corre Porta, Court Goodman, Cummere Mayo, Dale Innis, Darien Caldwell, Darjeeling Schoonhoven, Daten Thielt, dimentox travanti, Dirk Talamasca, Drew Dwi, Duckless Vandyke, Elanthius Flagstaff, Electro Burnstein, emiley tomsen, Escort DeFarge, Eva Rau, Ezian Ecksol, Fire Centaur, Fluf Fredriksson, Francisco Koolhoven, Frontera Thor, Frungi Stastny, Gally Young, gearsawe stonecutter, Gigs Taggart, Gordon Wendt, Gudmund Shepherd, Gypsy Paz, Harleen Gretzky, Henri Beauchamp, Inma Rau, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Jessicka Graves, Joeseph Albanese, Joshua Philgarlic, Khyota Wulluf, kirstenlee Cinquetti, Latif Khalifa, Lex Neva, Lilibeth Andree, Lisa Lowe, Lunita Savira, Loosey Demonia, lum pfohl, Marcos Fonzarelli, MartinRJ Fayray, Marusame Arai, Matthew Dowd, Maya Remblai, McCabe Maxsted, Meghan Dench, Melchoir Tokhes, Menos Short, Michelle2 Zenovka, Mimika Oh, Minerva Memel, Mm Alder, Ochi Wolfe, Omei Turnbull, Pesho Replacement, Phantom Ninetails, phoenixflames kukulcan, Polo Gufler, prez pessoa, princess niven, Prokofy Neva, Qie Niangao, Rem Beattie, RodneyLee Jessop, Saijanai Kuhn, Seg Baphomet, Sergen Davies, Shirley Marquez, SignpostMarv Martin, Sindy Tsure, Sira Arbizu, Skips Jigsaw, Sougent Harrop, Spritely Pixel, Squirrel Wood, StarSong Bright, Subversive Writer, Sugarcult Dagger, Sylumm Grigorovich, Tammy Nowotny, Tanooki Darkes, Tayra Dagostino, Theoretical Chemistry, Thickbrick Sleaford, valerie rosewood, Vex Streeter, Vixen Heron, Whoops Babii, Winter Ventura, Xiki Luik, Yann Dufaux, Yina Yao, Yukinoroh Kamachi, Zolute Infinity, Zwagoth Klaar
+
+
+To be a success in business, be daring, be first, be different. --Henry Marchant
+ </text_editor>
+ </panel>
+ <panel name="licenses_panel">
+ <text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
APR Copyright (C) 2000-2004 The Apache Software Foundation
cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
@@ -26,9 +35,9 @@ google-perftools Copyright (c) 2005, Google Inc.
All rights reserved. See licenses.txt for details.
Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
-
-To be a success in business, be daring, be first, be different. --Henry Marchant
</text_editor>
+ </panel>
+</tab_container>
<string name="you_are_at">
U bent op [POSITION]
</string>
diff --git a/indra/newview/skins/default/xui/nl/floater_map.xml b/indra/newview/skins/default/xui/nl/floater_map.xml
index 4bd691a96a..29af36e50c 100644
--- a/indra/newview/skins/default/xui/nl/floater_map.xml
+++ b/indra/newview/skins/default/xui/nl/floater_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Map">
- <floater.string name="mini_map_north">
- N
- </floater.string>
- <floater.string name="mini_map_east">
- O
- </floater.string>
- <floater.string name="mini_map_west">
- W
- </floater.string>
- <floater.string name="mini_map_south">
- Z
- </floater.string>
- <floater.string name="mini_map_southeast">
- ZO
- </floater.string>
- <floater.string name="mini_map_northeast">
- NO
- </floater.string>
- <floater.string name="mini_map_southwest">
- ZW
- </floater.string>
- <floater.string name="mini_map_northwest">
- NW
- </floater.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="O" name="floater_map_east" text="O">
- O
- </text>
- <text label="W" name="floater_map_west" text="W">
- W
- </text>
- <text label="Z" name="floater_map_south" text="Z">
- Z
- </text>
- <text label="ZO" name="floater_map_southeast" text="ZO">
- ZO
- </text>
- <text label="NO" name="floater_map_northeast" text="NO">
- NO
- </text>
- <text label="ZW" name="floater_map_southwest" text="ZW">
- ZW
- </text>
- <text label="NW" name="floater_map_northwest" text="NW">
- NW
- </text>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Map">
+ <floater.string name="mini_map_north">
+ N
+ </floater.string>
+ <floater.string name="mini_map_east">
+ O
+ </floater.string>
+ <floater.string name="mini_map_west">
+ W
+ </floater.string>
+ <floater.string name="mini_map_south">
+ Z
+ </floater.string>
+ <floater.string name="mini_map_southeast">
+ ZO
+ </floater.string>
+ <floater.string name="mini_map_northeast">
+ NO
+ </floater.string>
+ <floater.string name="mini_map_southwest">
+ ZW
+ </floater.string>
+ <floater.string name="mini_map_northwest">
+ NW
+ </floater.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="O" name="floater_map_east" text="O">
+ O
+ </text>
+ <text label="W" name="floater_map_west" text="W">
+ W
+ </text>
+ <text label="Z" name="floater_map_south" text="Z">
+ Z
+ </text>
+ <text label="ZO" name="floater_map_southeast" text="ZO">
+ ZO
+ </text>
+ <text label="NO" name="floater_map_northeast" text="NO">
+ NO
+ </text>
+ <text label="ZW" name="floater_map_southwest" text="ZW">
+ ZW
+ </text>
+ <text label="NW" name="floater_map_northwest" text="NW">
+ NW
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/nl/panel_world_map.xml b/indra/newview/skins/default/xui/nl/panel_world_map.xml
index 4df1ec10d8..11855b7fc1 100644
--- a/indra/newview/skins/default/xui/nl/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/nl/panel_world_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="world_map">
- <panel.string name="world_map_north">
- N
- </panel.string>
- <panel.string name="world_map_east">
- O
- </panel.string>
- <panel.string name="world_map_west">
- W
- </panel.string>
- <panel.string name="world_map_south">
- Z
- </panel.string>
- <panel.string name="world_map_southeast">
- ZO
- </panel.string>
- <panel.string name="world_map_northeast">
- NO
- </panel.string>
- <panel.string name="world_map_southwest">
- ZW
- </panel.string>
- <panel.string name="world_map_northwest">
- NW
- </panel.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="O" name="floater_map_east" text="O">
- O
- </text>
- <text label="W" name="floater_map_west" text="W">
- W
- </text>
- <text label="Z" name="floater_map_south" text="Z">
- Z
- </text>
- <text label="ZO" name="floater_map_southeast" text="ZO">
- ZO
- </text>
- <text label="NO" name="floater_map_northeast" text="NO">
- NO
- </text>
- <text label="ZW" name="floater_map_southwest" text="ZW">
- ZW
- </text>
- <text label="NW" name="floater_map_northwest" text="NW">
- NW
- </text>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="world_map">
+ <panel.string name="world_map_north">
+ N
+ </panel.string>
+ <panel.string name="world_map_east">
+ O
+ </panel.string>
+ <panel.string name="world_map_west">
+ W
+ </panel.string>
+ <panel.string name="world_map_south">
+ Z
+ </panel.string>
+ <panel.string name="world_map_southeast">
+ ZO
+ </panel.string>
+ <panel.string name="world_map_northeast">
+ NO
+ </panel.string>
+ <panel.string name="world_map_southwest">
+ ZW
+ </panel.string>
+ <panel.string name="world_map_northwest">
+ NW
+ </panel.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="O" name="floater_map_east" text="O">
+ O
+ </text>
+ <text label="W" name="floater_map_west" text="W">
+ W
+ </text>
+ <text label="Z" name="floater_map_south" text="Z">
+ Z
+ </text>
+ <text label="ZO" name="floater_map_southeast" text="ZO">
+ ZO
+ </text>
+ <text label="NO" name="floater_map_northeast" text="NO">
+ NO
+ </text>
+ <text label="ZW" name="floater_map_southwest" text="ZW">
+ ZW
+ </text>
+ <text label="NW" name="floater_map_northwest" text="NW">
+ NW
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml
index bbf8165883..0f100b9d83 100755
--- a/indra/newview/skins/default/xui/pl/floater_about.xml
+++ b/indra/newview/skins/default/xui/pl/floater_about.xml
@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="floater_about" title="O [APP_NAME]">
+<tab_container name="about_tab">
+ <panel name="credits_panel">
<text_editor name="credits_editor">
Second Life zostało stworzone dla Was przez: Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl i wielu innych.
Podziękowania dla następujących rezydentów za pomoc w pracy nad obecną wersją Second Life: able whitman, Adeon Writer, adonaira aabye, Aeron Kohime, Agathos Frascati, Aimee Trescothick, Aleric Inglewood, Alissa Sabre, Aminom Marvin, Angela Talamasca, Aralara Rajal, Armin Weatherwax, Ashrilyn Hayashida, Athanasius Skytower, Aura Dirval, Barney Boomslang, Biancaluce Robbiani, Biker Offcourse, Borg Capalini, Bulli Schumann, catherine pfeffer, Chalice Yao, Corre Porta, Court Goodman, Cummere Mayo, Dale Innis, Darien Caldwell, Darjeeling Schoonhoven, Daten Thielt, dimentox travanti, Dirk Talamasca, Drew Dwi, Duckless Vandyke, Elanthius Flagstaff, Electro Burnstein, emiley tomsen, Escort DeFarge, Eva Rau, Ezian Ecksol, Fire Centaur, Fluf Fredriksson, Francisco Koolhoven, Frontera Thor, Frungi Stastny, Gally Young, gearsawe stonecutter, Gigs Taggart, Gordon Wendt, Gudmund Shepherd, Gypsy Paz, Harleen Gretzky, Henri Beauchamp, Inma Rau, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Jessicka Graves, Joeseph Albanese, Joshua Philgarlic, Khyota Wulluf, kirstenlee Cinquetti, Latif Khalifa, Lex Neva, Lilibeth Andree, Lisa Lowe, Lunita Savira, Loosey Demonia, lum pfohl, Marcos Fonzarelli, MartinRJ Fayray, Marusame Arai, Matthew Dowd, Maya Remblai, McCabe Maxsted, Meghan Dench, Melchoir Tokhes, Menos Short, Michelle2 Zenovka, Mimika Oh, Minerva Memel, Mm Alder, Ochi Wolfe, Omei Turnbull, Pesho Replacement, Phantom Ninetails, phoenixflames kukulcan, Polo Gufler, prez pessoa, princess niven, Prokofy Neva, Qie Niangao, Rem Beattie, RodneyLee Jessop, Saijanai Kuhn, Seg Baphomet, Sergen Davies, Shirley Marquez, SignpostMarv Martin, Sindy Tsure, Sira Arbizu, Skips Jigsaw, Sougent Harrop, Spritely Pixel, Squirrel Wood, StarSong Bright, Subversive Writer, Sugarcult Dagger, Sylumm Grigorovich, Tammy Nowotny, Tanooki Darkes, Tayra Dagostino, Theoretical Chemistry, Thickbrick Sleaford, valerie rosewood, Vex Streeter, Vixen Heron, Whoops Babii, Winter Ventura, Xiki Luik, Yann Dufaux, Yina Yao, Yukinoroh Kamachi, Zolute Infinity, Zwagoth Klaar
+
+
+ I get by with a little help from my friends. --Richard Starkey
+ </text_editor>
+ </panel>
+ <panel name="licenses_panel">
+ <text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
APR Copyright (C) 2000-2004 The Apache Software Foundation
cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
@@ -25,11 +34,9 @@
Wszystkie prawa zastrzeżone. Szczegóły w pliku licenses.txt.
Programowanie dźwięku czatu: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
-
- Polska wersja klienta: Malwina Dollinger, Magnus Balczo, Identity Euler
-
- I get by with a little help from my friends. --Richard Starkey
</text_editor>
+ </panel>
+</tab_container>
<string name="you_are_at">
Położenie: [POSITION]
</string>
diff --git a/indra/newview/skins/default/xui/pl/floater_map.xml b/indra/newview/skins/default/xui/pl/floater_map.xml
index 361f8f4f49..6eabde7c52 100644
--- a/indra/newview/skins/default/xui/pl/floater_map.xml
+++ b/indra/newview/skins/default/xui/pl/floater_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Map">
- <floater.string name="mini_map_north">
- N
- </floater.string>
- <floater.string name="mini_map_east">
- E
- </floater.string>
- <floater.string name="mini_map_west">
- W
- </floater.string>
- <floater.string name="mini_map_south">
- S
- </floater.string>
- <floater.string name="mini_map_southeast">
- SE
- </floater.string>
- <floater.string name="mini_map_northeast">
- NE
- </floater.string>
- <floater.string name="mini_map_southwest">
- SW
- </floater.string>
- <floater.string name="mini_map_northwest">
- NW
- </floater.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="E" name="floater_map_east" text="E">
- E
- </text>
- <text label="W" name="floater_map_west" text="W">
- W
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SE" name="floater_map_southeast" text="SE">
- SE
- </text>
- <text label="NE" name="floater_map_northeast" text="NE">
- NE
- </text>
- <text label="SW" name="floater_map_southwest" text="SW">
- SW
- </text>
- <text label="NW" name="floater_map_northwest" text="NW">
- NW
- </text>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Map">
+ <floater.string name="mini_map_north">
+ N
+ </floater.string>
+ <floater.string name="mini_map_east">
+ E
+ </floater.string>
+ <floater.string name="mini_map_west">
+ W
+ </floater.string>
+ <floater.string name="mini_map_south">
+ S
+ </floater.string>
+ <floater.string name="mini_map_southeast">
+ SE
+ </floater.string>
+ <floater.string name="mini_map_northeast">
+ NE
+ </floater.string>
+ <floater.string name="mini_map_southwest">
+ SW
+ </floater.string>
+ <floater.string name="mini_map_northwest">
+ NW
+ </floater.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="E" name="floater_map_east" text="E">
+ E
+ </text>
+ <text label="W" name="floater_map_west" text="W">
+ W
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SE" name="floater_map_southeast" text="SE">
+ SE
+ </text>
+ <text label="NE" name="floater_map_northeast" text="NE">
+ NE
+ </text>
+ <text label="SW" name="floater_map_southwest" text="SW">
+ SW
+ </text>
+ <text label="NW" name="floater_map_northwest" text="NW">
+ NW
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/pl/panel_preferences_advanced.xml
index 75a9efcd0a..2b70a728fa 100644
--- a/indra/newview/skins/default/xui/pl/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_advanced.xml
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="advanced">
- <text name="AspectRatioLabel1" tool_tip="width / height">
- Proporcje:
- </text>
- <combo_box name="aspect_ratio" tool_tip="width / height">
- <combo_box.item label="4:3 (Standardowy CRT)" name="item1"/>
- <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
- <combo_box.item label="8:5 (Panoramiczny)" name="item3"/>
- <combo_box.item label="16:9 (Panoramiczny)" name="item4"/>
- </combo_box>
-</panel>
+<?xml version="1.0" encoding="utf-8"?>
+<panel name="advanced">
+ <text name="AspectRatioLabel1" tool_tip="width / height">
+ Proporcje:
+ </text>
+ <combo_box name="aspect_ratio" tool_tip="width / height">
+ <combo_box.item label="4:3 (Standardowy CRT)" name="item1"/>
+ <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
+ <combo_box.item label="8:5 (Panoramiczny)" name="item3"/>
+ <combo_box.item label="16:9 (Panoramiczny)" name="item4"/>
+ </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_world_map.xml b/indra/newview/skins/default/xui/pl/panel_world_map.xml
index babb9fbae1..608f102dc9 100644
--- a/indra/newview/skins/default/xui/pl/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/pl/panel_world_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="world_map">
- <panel.string name="world_map_north">
- N
- </panel.string>
- <panel.string name="world_map_east">
- E
- </panel.string>
- <panel.string name="world_map_west">
- W
- </panel.string>
- <panel.string name="world_map_south">
- S
- </panel.string>
- <panel.string name="world_map_southeast">
- SE
- </panel.string>
- <panel.string name="world_map_northeast">
- NE
- </panel.string>
- <panel.string name="world_map_southwest">
- SW
- </panel.string>
- <panel.string name="world_map_northwest">
- NW
- </panel.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="E" name="floater_map_east" text="E">
- E
- </text>
- <text label="W" name="floater_map_west" text="W">
- W
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SE" name="floater_map_southeast" text="SE">
- SE
- </text>
- <text label="NE" name="floater_map_northeast" text="NE">
- NE
- </text>
- <text label="SW" name="floater_map_southwest" text="SW">
- SW
- </text>
- <text label="NW" name="floater_map_northwest" text="NW">
- NW
- </text>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="world_map">
+ <panel.string name="world_map_north">
+ N
+ </panel.string>
+ <panel.string name="world_map_east">
+ E
+ </panel.string>
+ <panel.string name="world_map_west">
+ W
+ </panel.string>
+ <panel.string name="world_map_south">
+ S
+ </panel.string>
+ <panel.string name="world_map_southeast">
+ SE
+ </panel.string>
+ <panel.string name="world_map_northeast">
+ NE
+ </panel.string>
+ <panel.string name="world_map_southwest">
+ SW
+ </panel.string>
+ <panel.string name="world_map_northwest">
+ NW
+ </panel.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="E" name="floater_map_east" text="E">
+ E
+ </text>
+ <text label="W" name="floater_map_west" text="W">
+ W
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SE" name="floater_map_southeast" text="SE">
+ SE
+ </text>
+ <text label="NE" name="floater_map_northeast" text="NE">
+ NE
+ </text>
+ <text label="SW" name="floater_map_southwest" text="SW">
+ SW
+ </text>
+ <text label="NW" name="floater_map_northwest" text="NW">
+ NW
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml
index c8c0442d1d..12cc879cbc 100644
--- a/indra/newview/skins/default/xui/pt/floater_about.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about.xml
@@ -1,10 +1,18 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_about" title="Sobre o [APP_NAME]">
+<tab_container name="about_tab">
+ <panel name="credits_panel">
<text_editor name="credits_editor">
Second Life é oferecido a você por Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl e muitos outros.
Obrigado aos seguintes residentes por ajudar a garantir para que esta versão seja ainda melhor: able whitman, Adeon Writer, adonaira aabye, Aeron Kohime, Agathos Frascati, Aimee Trescothick, Aleric Inglewood, Alissa Sabre, Aminom Marvin, Angela Talamasca, Aralara Rajal, Armin Weatherwax, Ashrilyn Hayashida, Athanasius Skytower, Aura Dirval, Barney Boomslang, Biancaluce Robbiani, Biker Offcourse, Borg Capalini, Bulli Schumann, catherine pfeffer, Chalice Yao, Corre Porta, Court Goodman, Cummere Mayo, Dale Innis, Darien Caldwell, Darjeeling Schoonhoven, Daten Thielt, dimentox travanti, Dirk Talamasca, Drew Dwi, Duckless Vandyke, Elanthius Flagstaff, Electro Burnstein, emiley tomsen, Escort DeFarge, Eva Rau, Ezian Ecksol, Fire Centaur, Fluf Fredriksson, Francisco Koolhoven, Frontera Thor, Frungi Stastny, Gally Young, gearsawe stonecutter, Gigs Taggart, Gordon Wendt, Gudmund Shepherd, Gypsy Paz, Harleen Gretzky, Henri Beauchamp, Inma Rau, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Jessicka Graves, Joeseph Albanese, Joshua Philgarlic, Khyota Wulluf, kirstenlee Cinquetti, Latif Khalifa, Lex Neva, Lilibeth Andree, Lisa Lowe, Lunita Savira, Loosey Demonia, lum pfohl, Marcos Fonzarelli, MartinRJ Fayray, Marusame Arai, Matthew Dowd, Maya Remblai, McCabe Maxsted, Meghan Dench, Melchoir Tokhes, Menos Short, Michelle2 Zenovka, Mimika Oh, Minerva Memel, Mm Alder, Ochi Wolfe, Omei Turnbull, Pesho Replacement, Phantom Ninetails, phoenixflames kukulcan, Polo Gufler, prez pessoa, princess niven, Prokofy Neva, Qie Niangao, Rem Beattie, RodneyLee Jessop, Saijanai Kuhn, Seg Baphomet, Sergen Davies, Shirley Marquez, SignpostMarv Martin, Sindy Tsure, Sira Arbizu, Skips Jigsaw, Sougent Harrop, Spritely Pixel, Squirrel Wood, StarSong Bright, Subversive Writer, Sugarcult Dagger, Sylumm Grigorovich, Tammy Nowotny, Tanooki Darkes, Tayra Dagostino, Theoretical Chemistry, Thickbrick Sleaford, valerie rosewood, Vex Streeter, Vixen Heron, Whoops Babii, Winter Ventura, Xiki Luik, Yann Dufaux, Yina Yao, Yukinoroh Kamachi, Zolute Infinity, Zwagoth Klaar
+
+ Para ter sucesso nos negócios, seja ousado, seja o primeiro, seja diferente. --Henry Marchant
+ </text_editor>
+ </panel>
+ <panel name="licenses_panel">
+ <text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
APR Copyright (C) 2000-2004 The Apache Software Foundation
cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
@@ -26,10 +34,9 @@
Todos os direitos reservados. Veja licenças.txt para detalhes.
Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
-
-
- Para ter sucesso nos negócios, seja ousado, seja o primeiro, seja diferente. --Henry Marchant
</text_editor>
+ </panel>
+</tab_container>
<string name="you_are_at">
Você está em [POSITION]
</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_map.xml b/indra/newview/skins/default/xui/pt/floater_map.xml
index eb55560a1e..ff60f77c4b 100644
--- a/indra/newview/skins/default/xui/pt/floater_map.xml
+++ b/indra/newview/skins/default/xui/pt/floater_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Map">
- <floater.string name="mini_map_north">
- N
- </floater.string>
- <floater.string name="mini_map_east">
- L
- </floater.string>
- <floater.string name="mini_map_west">
- O
- </floater.string>
- <floater.string name="mini_map_south">
- S
- </floater.string>
- <floater.string name="mini_map_southeast">
- SE
- </floater.string>
- <floater.string name="mini_map_northeast">
- NE
- </floater.string>
- <floater.string name="mini_map_southwest">
- SO
- </floater.string>
- <floater.string name="mini_map_northwest">
- NO
- </floater.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="L" name="floater_map_east" text="L">
- L
- </text>
- <text label="O" name="floater_map_west" text="O">
- O
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SE" name="floater_map_southeast" text="SE">
- SE
- </text>
- <text label="NE" name="floater_map_northeast" text="NE">
- NE
- </text>
- <text label="SO" name="floater_map_southwest" text="SO">
- SO
- </text>
- <text label="NO" name="floater_map_northwest" text="NO">
- NO
- </text>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Map">
+ <floater.string name="mini_map_north">
+ N
+ </floater.string>
+ <floater.string name="mini_map_east">
+ L
+ </floater.string>
+ <floater.string name="mini_map_west">
+ O
+ </floater.string>
+ <floater.string name="mini_map_south">
+ S
+ </floater.string>
+ <floater.string name="mini_map_southeast">
+ SE
+ </floater.string>
+ <floater.string name="mini_map_northeast">
+ NE
+ </floater.string>
+ <floater.string name="mini_map_southwest">
+ SO
+ </floater.string>
+ <floater.string name="mini_map_northwest">
+ NO
+ </floater.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="L" name="floater_map_east" text="L">
+ L
+ </text>
+ <text label="O" name="floater_map_west" text="O">
+ O
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SE" name="floater_map_southeast" text="SE">
+ SE
+ </text>
+ <text label="NE" name="floater_map_northeast" text="NE">
+ NE
+ </text>
+ <text label="SO" name="floater_map_southwest" text="SO">
+ SO
+ </text>
+ <text label="NO" name="floater_map_northwest" text="NO">
+ NO
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml
index b53fe51509..5ca80bd74d 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="advanced">
- <text name="AspectRatioLabel1" tool_tip="largura / altura">
- Relação de Aspecto:
- </text>
- <combo_box name="aspect_ratio" tool_tip="largura / altura">
- <combo_box.item label="4:3 (CRT Padrão)" name="item1"/>
- <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
- <combo_box.item label="8:5 (tela ampla)" name="item3"/>
- <combo_box.item label="16:9 (tela ampla)" name="item4"/>
- </combo_box>
-</panel>
+<?xml version="1.0" encoding="utf-8"?>
+<panel name="advanced">
+ <text name="AspectRatioLabel1" tool_tip="largura / altura">
+ Relação de Aspecto:
+ </text>
+ <combo_box name="aspect_ratio" tool_tip="largura / altura">
+ <combo_box.item label="4:3 (CRT Padrão)" name="item1"/>
+ <combo_box.item label="5:4 (1280x1024 LCD)" name="item2"/>
+ <combo_box.item label="8:5 (tela ampla)" name="item3"/>
+ <combo_box.item label="16:9 (tela ampla)" name="item4"/>
+ </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_world_map.xml b/indra/newview/skins/default/xui/pt/panel_world_map.xml
index ed63b1eb0d..2fda713ec7 100644
--- a/indra/newview/skins/default/xui/pt/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/pt/panel_world_map.xml
@@ -1,51 +1,51 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="world_map">
- <panel.string name="world_map_north">
- N
- </panel.string>
- <panel.string name="world_map_east">
- L
- </panel.string>
- <panel.string name="world_map_west">
- O
- </panel.string>
- <panel.string name="world_map_south">
- S
- </panel.string>
- <panel.string name="world_map_southeast">
- SE
- </panel.string>
- <panel.string name="world_map_northeast">
- NE
- </panel.string>
- <panel.string name="world_map_southwest">
- SO
- </panel.string>
- <panel.string name="world_map_northwest">
- NO
- </panel.string>
- <text label="N" name="floater_map_north" text="N">
- N
- </text>
- <text label="L" name="floater_map_east" text="L">
- L
- </text>
- <text label="O" name="floater_map_west" text="O">
- O
- </text>
- <text label="S" name="floater_map_south" text="S">
- S
- </text>
- <text label="SE" name="floater_map_southeast" text="SE">
- SE
- </text>
- <text label="NE" name="floater_map_northeast" text="NE">
- NE
- </text>
- <text label="SO" name="floater_map_southwest" text="SO">
- SO
- </text>
- <text label="NO" name="floater_map_northwest" text="NO">
- NO
- </text>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="world_map">
+ <panel.string name="world_map_north">
+ N
+ </panel.string>
+ <panel.string name="world_map_east">
+ L
+ </panel.string>
+ <panel.string name="world_map_west">
+ O
+ </panel.string>
+ <panel.string name="world_map_south">
+ S
+ </panel.string>
+ <panel.string name="world_map_southeast">
+ SE
+ </panel.string>
+ <panel.string name="world_map_northeast">
+ NE
+ </panel.string>
+ <panel.string name="world_map_southwest">
+ SO
+ </panel.string>
+ <panel.string name="world_map_northwest">
+ NO
+ </panel.string>
+ <text label="N" name="floater_map_north" text="N">
+ N
+ </text>
+ <text label="L" name="floater_map_east" text="L">
+ L
+ </text>
+ <text label="O" name="floater_map_west" text="O">
+ O
+ </text>
+ <text label="S" name="floater_map_south" text="S">
+ S
+ </text>
+ <text label="SE" name="floater_map_southeast" text="SE">
+ SE
+ </text>
+ <text label="NE" name="floater_map_northeast" text="NE">
+ NE
+ </text>
+ <text label="SO" name="floater_map_southwest" text="SO">
+ SO
+ </text>
+ <text label="NO" name="floater_map_northwest" text="NO">
+ NO
+ </text>
+</panel>
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 bda81a505d..e98ef4749b 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -270,7 +270,6 @@ class WindowsManifest(ViewerManifest):
self.path("fmod.dll")
self.enable_no_crt_manifest_check()
-
# Media plugins - QuickTime
if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_quicktime.dll")
@@ -319,10 +318,12 @@ class WindowsManifest(ViewerManifest):
# Vivox runtimes
if self.prefix(src=self.args['configuration'], 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
@@ -536,10 +537,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")
libdir = "../../libraries/universal-darwin/lib_release"
@@ -809,7 +811,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):