summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2012-02-27 14:48:39 -0500
committerNat Goodspeed <nat@lindenlab.com>2012-02-27 14:48:39 -0500
commit063edac43f90d2cb0d2b41db939bbf919a1a3217 (patch)
treebbf1d446baef80933f6be80d05734d68144ae4cc
parent6f53796ccf4dc29368920a322baeaceb3fd2266f (diff)
parente7ab3da7a7f5c68e3544a64c30f011762572995a (diff)
Automated merge with file:///Users/nat/linden/viewer-leap-daggy
-rw-r--r--.hgtags20
-rw-r--r--autobuild.xml12
-rw-r--r--doc/contributions.txt8
-rw-r--r--indra/CMakeLists.txt1
-rw-r--r--indra/cmake/LLTestCommand.cmake3
-rw-r--r--indra/integration_tests/llui_libtest/CMakeLists.txt2
-rw-r--r--indra/lib/python/indra/util/llmanifest.py46
-rw-r--r--indra/linux_updater/CMakeLists.txt6
-rw-r--r--indra/llaudio/llaudioengine.cpp23
-rw-r--r--indra/llaudio/llaudioengine.h1
-rw-r--r--indra/llcommon/CMakeLists.txt16
-rw-r--r--indra/llcommon/llerror.cpp6
-rw-r--r--indra/llcommon/llerrorcontrol.h1
-rw-r--r--indra/llcommon/llinitparam.cpp (renamed from indra/llxuixml/llinitparam.cpp)0
-rw-r--r--indra/llcommon/llinitparam.h (renamed from indra/llxuixml/llinitparam.h)14
-rw-r--r--indra/llcommon/llinstancetracker.h21
-rw-r--r--indra/llcommon/llprocess.cpp1189
-rw-r--r--indra/llcommon/llprocess.h519
-rw-r--r--indra/llcommon/llprocesslauncher.cpp357
-rw-r--r--indra/llcommon/llprocesslauncher.h90
-rw-r--r--indra/llcommon/llqueuedthread.cpp4
-rw-r--r--indra/llcommon/llqueuedthread.h4
-rw-r--r--indra/llcommon/llregistry.h (renamed from indra/llxuixml/llregistry.h)0
-rw-r--r--indra/llcommon/llsdparam.cpp (renamed from indra/llui/llsdparam.cpp)0
-rw-r--r--indra/llcommon/llsdparam.h (renamed from indra/llui/llsdparam.h)6
-rw-r--r--indra/llcommon/llstreamqueue.cpp24
-rw-r--r--indra/llcommon/llstreamqueue.h240
-rw-r--r--indra/llcommon/llstring.cpp16
-rw-r--r--indra/llcommon/llstring.h593
-rw-r--r--indra/llcommon/llsys.cpp18
-rw-r--r--indra/llcommon/llthread.cpp15
-rw-r--r--indra/llcommon/llthread.h8
-rw-r--r--indra/llcommon/llversionviewer.h4
-rw-r--r--indra/llcommon/llworkerthread.cpp2
-rw-r--r--indra/llcommon/llworkerthread.h2
-rw-r--r--indra/llcommon/tests/StringVec.h37
-rw-r--r--indra/llcommon/tests/listener.h21
-rw-r--r--indra/llcommon/tests/llinstancetracker_test.cpp7
-rw-r--r--indra/llcommon/tests/llprocess_test.cpp1271
-rw-r--r--indra/llcommon/tests/llsdserialize_test.cpp274
-rw-r--r--indra/llcommon/tests/llstreamqueue_test.cpp197
-rw-r--r--indra/llcommon/tests/llstring_test.cpp118
-rw-r--r--indra/llcommon/tests/setpython.py19
-rw-r--r--indra/llimage/llimageworker.cpp2
-rw-r--r--indra/llimage/llimageworker.h2
-rw-r--r--indra/llmath/lloctree.h36
-rw-r--r--indra/llmath/llvolume.cpp88
-rw-r--r--indra/llmath/llvolume.h2
-rw-r--r--indra/llmessage/llbuffer.cpp90
-rw-r--r--indra/llmessage/llbuffer.h25
-rw-r--r--indra/llmessage/llbufferstream.cpp8
-rw-r--r--indra/llmessage/llcurl.cpp426
-rw-r--r--indra/llmessage/llcurl.h30
-rw-r--r--indra/llmessage/llhttpassetstorage.cpp10
-rw-r--r--indra/llmessage/llhttpclient.cpp12
-rw-r--r--indra/llmessage/lliohttpserver.cpp4
-rw-r--r--indra/llmessage/lliopipe.cpp6
-rw-r--r--indra/llmessage/lliopipe.h2
-rw-r--r--indra/llmessage/lliosocket.cpp3
-rw-r--r--indra/llmessage/llpumpio.cpp51
-rw-r--r--indra/llmessage/llpumpio.h13
-rw-r--r--indra/llmessage/llsdrpcclient.h22
-rw-r--r--indra/llmessage/llurlrequest.cpp30
-rw-r--r--indra/llmessage/llurlrequest.h2
-rw-r--r--indra/llmessage/tests/llsdmessage_test.cpp36
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp47
-rw-r--r--indra/llplugin/llpluginprocessparent.h20
-rw-r--r--indra/llrender/llglslshader.cpp2
-rw-r--r--indra/llrender/llglslshader.h1
-rw-r--r--indra/llrender/llrender.cpp4
-rw-r--r--indra/llrender/llrendertarget.cpp3
-rw-r--r--indra/llrender/llshadermgr.cpp20
-rw-r--r--indra/llrender/llvertexbuffer.cpp130
-rw-r--r--indra/llrender/llvertexbuffer.h24
-rw-r--r--indra/llui/CMakeLists.txt10
-rw-r--r--indra/llui/llbutton.cpp18
-rw-r--r--indra/llui/lllayoutstack.cpp829
-rw-r--r--indra/llui/lllayoutstack.h94
-rw-r--r--indra/llui/llmenugl.cpp7
-rw-r--r--indra/llui/llpanel.h2
-rw-r--r--indra/llui/llresizebar.cpp4
-rw-r--r--indra/llui/llresizebar.h1
-rw-r--r--indra/llui/llscrollcontainer.cpp99
-rw-r--r--indra/llui/lltabcontainer.cpp13
-rw-r--r--indra/llui/lltextbase.cpp42
-rw-r--r--indra/llui/lltextbase.h2
-rw-r--r--indra/llui/lltexteditor.cpp26
-rw-r--r--indra/llui/lltexteditor.h5
-rw-r--r--indra/llui/lltoolbar.cpp9
-rw-r--r--indra/llui/lltoolbar.h1
-rw-r--r--indra/llui/lltrans.cpp (renamed from indra/llxuixml/lltrans.cpp)0
-rw-r--r--indra/llui/lltrans.h (renamed from indra/llxuixml/lltrans.h)0
-rw-r--r--indra/llui/lluicolor.cpp (renamed from indra/llxuixml/lluicolor.cpp)0
-rw-r--r--indra/llui/lluicolor.h (renamed from indra/llxuixml/lluicolor.h)0
-rw-r--r--indra/llui/llview.cpp11
-rw-r--r--indra/llui/llview.h2
-rw-r--r--indra/llui/llwindowshade.cpp210
-rw-r--r--indra/llui/llwindowshade.h16
-rw-r--r--indra/llui/llxuiparser.cpp (renamed from indra/llxuixml/llxuiparser.cpp)0
-rw-r--r--indra/llui/llxuiparser.h (renamed from indra/llxuixml/llxuiparser.h)0
-rw-r--r--indra/llui/tests/llurlentry_stub.cpp22
-rw-r--r--indra/llui/tests/llurlentry_test.cpp15
-rw-r--r--indra/llui/tests/llurlmatch_test.cpp34
-rw-r--r--indra/llwindow/llwindow.cpp4
-rw-r--r--indra/llwindow/llwindowwin32.cpp33
-rw-r--r--indra/llxuixml/CMakeLists.txt45
-rw-r--r--indra/newview/CMakeLists.txt11
-rw-r--r--indra/newview/app_settings/commands.xml10
-rw-r--r--indra/newview/app_settings/settings.xml109
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cofF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl8
-rwxr-xr-xindra/newview/llagent.cpp1
-rw-r--r--indra/newview/llagentwearables.cpp11
-rw-r--r--indra/newview/llagentwearablesfetch.cpp14
-rw-r--r--indra/newview/llagentwearablesfetch.h2
-rw-r--r--indra/newview/llappearancemgr.cpp9
-rw-r--r--indra/newview/llappviewer.cpp18
-rwxr-xr-xindra/newview/llavataractions.cpp21
-rwxr-xr-x[-rw-r--r--]indra/newview/llavatariconctrl.cpp3
-rw-r--r--indra/newview/llchathistory.cpp1
-rw-r--r--indra/newview/llchiclet.cpp13
-rw-r--r--indra/newview/llchicletbar.cpp29
-rw-r--r--indra/newview/llcommandlineparser.cpp9
-rw-r--r--indra/newview/lldrawable.cpp10
-rw-r--r--indra/newview/lldrawpoolavatar.cpp6
-rw-r--r--indra/newview/lldrawpoolbump.cpp79
-rw-r--r--indra/newview/llexternaleditor.cpp73
-rw-r--r--indra/newview/llexternaleditor.h6
-rw-r--r--indra/newview/llface.cpp199
-rw-r--r--indra/newview/llfavoritesbar.cpp4
-rw-r--r--indra/newview/llfilepicker.cpp41
-rw-r--r--indra/newview/llfilepicker.h2
-rw-r--r--indra/newview/llfloatercolorpicker.cpp2
-rw-r--r--indra/newview/llfloaterimagepreview.cpp11
-rw-r--r--indra/newview/llfloaterland.cpp22
-rw-r--r--indra/newview/llfloatermediasettings.cpp11
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp12
-rw-r--r--indra/newview/llfloaternamedesc.cpp21
-rw-r--r--indra/newview/llfloaternamedesc.h10
-rw-r--r--indra/newview/llfloaternotificationsconsole.cpp2
-rw-r--r--indra/newview/llfloateropenobject.cpp60
-rw-r--r--indra/newview/llfloateropenobject.h11
-rw-r--r--indra/newview/llfloateroutbox.cpp567
-rw-r--r--indra/newview/llfloateroutbox.h114
-rw-r--r--indra/newview/llfloatersnapshot.cpp15
-rw-r--r--indra/newview/llfloatertools.cpp4
-rw-r--r--indra/newview/llfloatertranslationsettings.cpp2
-rw-r--r--indra/newview/llfloateruipreview.cpp6
-rw-r--r--indra/newview/llfolderview.cpp45
-rw-r--r--indra/newview/llfolderview.h7
-rw-r--r--indra/newview/llfolderviewitem.cpp438
-rw-r--r--indra/newview/llfolderviewitem.h25
-rw-r--r--indra/newview/llgrouplist.cpp2
-rw-r--r--indra/newview/llimfloater.cpp9
-rw-r--r--indra/newview/llinspectremoteobject.cpp24
-rw-r--r--indra/newview/llinventorybridge.cpp946
-rw-r--r--indra/newview/llinventorybridge.h20
-rw-r--r--indra/newview/llinventoryfunctions.cpp130
-rw-r--r--indra/newview/llinventoryfunctions.h5
-rw-r--r--indra/newview/llinventorymodel.cpp119
-rw-r--r--indra/newview/llinventorymodel.h8
-rw-r--r--indra/newview/llinventorypanel.cpp38
-rw-r--r--indra/newview/llinventorypanel.h3
-rw-r--r--indra/newview/llmarketplacefunctions.cpp463
-rw-r--r--indra/newview/llmarketplacefunctions.h94
-rw-r--r--indra/newview/llmarketplacenotifications.cpp90
-rw-r--r--indra/newview/llmarketplacenotifications.h57
-rw-r--r--indra/newview/llmediactrl.cpp46
-rwxr-xr-x[-rw-r--r--]indra/newview/llmeshrepository.cpp148
-rw-r--r--indra/newview/llmeshrepository.h6
-rw-r--r--indra/newview/llnearbychatbar.cpp18
-rw-r--r--indra/newview/llnearbychatbar.h2
-rw-r--r--indra/newview/llnotificationhandler.h10
-rw-r--r--indra/newview/llnotificationmanager.cpp2
-rw-r--r--indra/newview/llpanelgrouplandmoney.cpp4
-rw-r--r--indra/newview/llpanelmaininventory.cpp11
-rw-r--r--indra/newview/llpanelmarketplaceinbox.cpp21
-rw-r--r--indra/newview/llpanelmarketplaceinbox.h7
-rw-r--r--indra/newview/llpanelmarketplaceoutbox.cpp363
-rw-r--r--indra/newview/llpanelmarketplaceoutbox.h90
-rw-r--r--indra/newview/llpanelmarketplaceoutboxinventory.cpp133
-rw-r--r--indra/newview/llpanelmarketplaceoutboxinventory.h27
-rw-r--r--indra/newview/llpanelpeople.cpp10
-rw-r--r--indra/newview/llpanelprimmediacontrols.cpp3
-rwxr-xr-xindra/newview/llpanelprofile.cpp2
-rw-r--r--indra/newview/llpanelteleporthistory.cpp2
-rw-r--r--indra/newview/llpreviewscript.cpp91
-rw-r--r--indra/newview/llpreviewscript.h6
-rw-r--r--indra/newview/llscriptfloater.cpp11
-rw-r--r--indra/newview/llselectmgr.cpp51
-rw-r--r--indra/newview/llsidepanelinventory.cpp387
-rw-r--r--indra/newview/llsidepanelinventory.h26
-rw-r--r--indra/newview/llspatialpartition.cpp73
-rw-r--r--indra/newview/llspatialpartition.h20
-rw-r--r--indra/newview/llstartup.cpp13
-rw-r--r--indra/newview/llsyswellwindow.cpp13
-rw-r--r--indra/newview/llsyswellwindow.h1
-rw-r--r--indra/newview/lltexlayer.h2
-rw-r--r--indra/newview/lltexturecache.cpp2
-rw-r--r--indra/newview/lltexturecache.h2
-rw-r--r--indra/newview/lltexturefetch.cpp2
-rw-r--r--indra/newview/lltexturefetch.h2
-rw-r--r--indra/newview/lltooldraganddrop.cpp27
-rw-r--r--indra/newview/lltooldraganddrop.h5
-rwxr-xr-xindra/newview/lltranslate.cpp18
-rwxr-xr-xindra/newview/lltranslate.h16
-rw-r--r--indra/newview/llviewerfloaterreg.cpp5
-rw-r--r--indra/newview/llviewermedia.cpp127
-rw-r--r--indra/newview/llviewermenu.cpp59
-rw-r--r--indra/newview/llviewerobject.cpp5
-rw-r--r--indra/newview/llviewerprecompiledheaders.h4
-rw-r--r--indra/newview/llviewerregion.cpp1
-rw-r--r--indra/newview/llviewershadermgr.cpp5
-rw-r--r--indra/newview/llviewertexture.cpp54
-rw-r--r--indra/newview/llviewertexturelist.cpp3
-rw-r--r--indra/newview/llviewerwindow.cpp31
-rw-r--r--indra/newview/llvoavatar.cpp32
-rw-r--r--indra/newview/llvoavatar.h7
-rw-r--r--indra/newview/llvoavatarself.cpp21
-rw-r--r--indra/newview/llvoavatarself.h3
-rw-r--r--indra/newview/llvoicevivox.cpp140
-rw-r--r--indra/newview/llvosurfacepatch.cpp2
-rw-r--r--indra/newview/llvovolume.cpp85
-rw-r--r--indra/newview/llvowater.cpp2
-rw-r--r--indra/newview/llvowlsky.cpp2
-rw-r--r--indra/newview/llwearablelist.cpp2
-rw-r--r--indra/newview/llxmlrpctransaction.cpp19
-rw-r--r--indra/newview/pipeline.cpp42
-rw-r--r--indra/newview/pipeline.h57
-rw-r--r--indra/newview/skins/default/textures/textures.xml20
-rw-r--r--indra/newview/skins/default/textures/toolbar_icons/outbox.pngbin0 -> 1521 bytes
-rw-r--r--indra/newview/skins/default/xui/da/menu_viewer.xml68
-rw-r--r--indra/newview/skins/default/xui/de/floater_about.xml48
-rw-r--r--indra/newview/skins/default/xui/de/floater_about_land.xml17
-rw-r--r--indra/newview/skins/default/xui/de/floater_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_camera.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_hardware_settings.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_model_preview.xml5
-rw-r--r--indra/newview/skins/default/xui/de/floater_model_wizard.xml3
-rw-r--r--indra/newview/skins/default/xui/de/floater_moveview.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_snapshot.xml122
-rw-r--r--indra/newview/skins/default/xui/de/floater_toybox.xml3
-rw-r--r--indra/newview/skins/default/xui/de/floater_translation_settings.xml58
-rw-r--r--indra/newview/skins/default/xui/de/floater_voice_controls.xml8
-rw-r--r--indra/newview/skins/default/xui/de/menu_toolbars.xml3
-rw-r--r--indra/newview/skins/default/xui/de/menu_viewer.xml58
-rw-r--r--indra/newview/skins/default/xui/de/notifications.xml36
-rw-r--r--indra/newview/skins/default/xui/de/panel_edit_skin.xml6
-rw-r--r--indra/newview/skins/default/xui/de/panel_postcard_message.xml21
-rw-r--r--indra/newview/skins/default/xui/de/panel_postcard_settings.xml23
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_chat.xml27
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml21
-rw-r--r--indra/newview/skins/default/xui/de/panel_snapshot_local.xml39
-rw-r--r--indra/newview/skins/default/xui/de/panel_snapshot_options.xml7
-rw-r--r--indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml17
-rw-r--r--indra/newview/skins/default/xui/de/panel_snapshot_profile.xml28
-rw-r--r--indra/newview/skins/default/xui/de/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml61
-rw-r--r--indra/newview/skins/default/xui/de/teleport_strings.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml54
-rw-r--r--indra/newview/skins/default/xui/en/floater_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_help_browser.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml5
-rw-r--r--indra/newview/skins/default/xui/en/floater_media_browser.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_merchant_outbox.xml152
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_wizard.xml32
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml206
-rw-r--r--indra/newview/skins/default/xui/en/floater_toybox.xml12
-rw-r--r--indra/newview/skins/default/xui/en/floater_ui_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_controls.xml5
-rw-r--r--indra/newview/skins/default/xui/en/floater_web_content.xml5
-rw-r--r--indra/newview/skins/default/xui/en/main_view.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_edit.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml9
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml6
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_add.xml1
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml53
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml212
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml100
-rw-r--r--indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_chiclet_bar.xml5
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified_info.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_profile.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_wearable.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_control_panel.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml5
-rw-r--r--indra/newview/skins/default/xui/en/panel_im_control_panel.xml23
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmarks.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_main_inventory.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml238
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_media.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_outbox_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_edit.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml5
-rw-r--r--indra/newview/skins/default/xui/en/panel_place_profile.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_places.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_postcard_settings.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_general.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_privacy.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_prim_media_controls.xml35
-rw-r--r--indra/newview/skins/default/xui/en/panel_progress.xml33
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_estate.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_script_ed.xml22
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_local.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_profile.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_toolbar_view.xml5
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_inventory.xml189
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml123
-rw-r--r--indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml10
-rw-r--r--indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml2
-rw-r--r--indra/newview/skins/default/xui/en/widgets/window_shade.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_about.xml48
-rw-r--r--indra/newview/skins/default/xui/es/floater_about_land.xml17
-rw-r--r--indra/newview/skins/default/xui/es/floater_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_camera.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_hardware_settings.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_model_preview.xml3
-rw-r--r--indra/newview/skins/default/xui/es/floater_model_wizard.xml3
-rw-r--r--indra/newview/skins/default/xui/es/floater_moveview.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_snapshot.xml122
-rw-r--r--indra/newview/skins/default/xui/es/floater_toybox.xml3
-rw-r--r--indra/newview/skins/default/xui/es/floater_translation_settings.xml58
-rw-r--r--indra/newview/skins/default/xui/es/floater_voice_controls.xml8
-rw-r--r--indra/newview/skins/default/xui/es/menu_toolbars.xml3
-rw-r--r--indra/newview/skins/default/xui/es/menu_viewer.xml58
-rw-r--r--indra/newview/skins/default/xui/es/notifications.xml40
-rw-r--r--indra/newview/skins/default/xui/es/panel_edit_skin.xml6
-rw-r--r--indra/newview/skins/default/xui/es/panel_nearby_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_postcard_message.xml21
-rw-r--r--indra/newview/skins/default/xui/es/panel_postcard_settings.xml23
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_chat.xml27
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml21
-rw-r--r--indra/newview/skins/default/xui/es/panel_snapshot_local.xml39
-rw-r--r--indra/newview/skins/default/xui/es/panel_snapshot_options.xml7
-rw-r--r--indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml17
-rw-r--r--indra/newview/skins/default/xui/es/panel_snapshot_profile.xml28
-rw-r--r--indra/newview/skins/default/xui/es/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml61
-rw-r--r--indra/newview/skins/default/xui/es/teleport_strings.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/floater_about.xml48
-rw-r--r--indra/newview/skins/default/xui/fr/floater_about_land.xml17
-rw-r--r--indra/newview/skins/default/xui/fr/floater_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_buy_currency.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/floater_camera.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_hardware_settings.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_model_preview.xml5
-rw-r--r--indra/newview/skins/default/xui/fr/floater_model_wizard.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/floater_moveview.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_snapshot.xml122
-rw-r--r--indra/newview/skins/default/xui/fr/floater_toybox.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/floater_translation_settings.xml58
-rw-r--r--indra/newview/skins/default/xui/fr/floater_voice_controls.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/menu_toolbars.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/menu_viewer.xml60
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml44
-rw-r--r--indra/newview/skins/default/xui/fr/panel_edit_skin.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/panel_nearby_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_postcard_message.xml21
-rw-r--r--indra/newview/skins/default/xui/fr/panel_postcard_settings.xml23
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_chat.xml27
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml21
-rw-r--r--indra/newview/skins/default/xui/fr/panel_snapshot_local.xml39
-rw-r--r--indra/newview/skins/default/xui/fr/panel_snapshot_options.xml7
-rw-r--r--indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml17
-rw-r--r--indra/newview/skins/default/xui/fr/panel_snapshot_profile.xml28
-rw-r--r--indra/newview/skins/default/xui/fr/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml61
-rw-r--r--indra/newview/skins/default/xui/fr/teleport_strings.xml4
-rw-r--r--indra/newview/skins/default/xui/it/floater_about.xml48
-rw-r--r--indra/newview/skins/default/xui/it/floater_about_land.xml17
-rw-r--r--indra/newview/skins/default/xui/it/floater_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_camera.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_hardware_settings.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_model_preview.xml3
-rw-r--r--indra/newview/skins/default/xui/it/floater_model_wizard.xml3
-rw-r--r--indra/newview/skins/default/xui/it/floater_moveview.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_snapshot.xml122
-rw-r--r--indra/newview/skins/default/xui/it/floater_toybox.xml3
-rw-r--r--indra/newview/skins/default/xui/it/floater_translation_settings.xml58
-rw-r--r--indra/newview/skins/default/xui/it/floater_voice_controls.xml8
-rw-r--r--indra/newview/skins/default/xui/it/menu_toolbars.xml3
-rw-r--r--indra/newview/skins/default/xui/it/menu_viewer.xml66
-rw-r--r--indra/newview/skins/default/xui/it/notifications.xml48
-rw-r--r--indra/newview/skins/default/xui/it/panel_edit_skin.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_postcard_message.xml21
-rw-r--r--indra/newview/skins/default/xui/it/panel_postcard_settings.xml23
-rw-r--r--indra/newview/skins/default/xui/it/panel_preferences_chat.xml27
-rw-r--r--indra/newview/skins/default/xui/it/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml21
-rw-r--r--indra/newview/skins/default/xui/it/panel_snapshot_local.xml39
-rw-r--r--indra/newview/skins/default/xui/it/panel_snapshot_options.xml7
-rw-r--r--indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml17
-rw-r--r--indra/newview/skins/default/xui/it/panel_snapshot_profile.xml28
-rw-r--r--indra/newview/skins/default/xui/it/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml61
-rw-r--r--indra/newview/skins/default/xui/it/teleport_strings.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about_land.xml17
-rw-r--r--indra/newview/skins/default/xui/ja/floater_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_camera.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_hardware_settings.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_model_preview.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/floater_model_wizard.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/floater_moveview.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_snapshot.xml122
-rw-r--r--indra/newview/skins/default/xui/ja/floater_toybox.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/floater_translation_settings.xml58
-rw-r--r--indra/newview/skins/default/xui/ja/floater_voice_controls.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/menu_toolbars.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/menu_viewer.xml56
-rw-r--r--indra/newview/skins/default/xui/ja/notifications.xml42
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_skin.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_postcard_message.xml21
-rw-r--r--indra/newview/skins/default/xui/ja/panel_postcard_settings.xml23
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_chat.xml27
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_general.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml21
-rw-r--r--indra/newview/skins/default/xui/ja/panel_snapshot_local.xml39
-rw-r--r--indra/newview/skins/default/xui/ja/panel_snapshot_options.xml7
-rw-r--r--indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml17
-rw-r--r--indra/newview/skins/default/xui/ja/panel_snapshot_profile.xml28
-rw-r--r--indra/newview/skins/default/xui/ja/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml61
-rw-r--r--indra/newview/skins/default/xui/ja/teleport_strings.xml4
-rw-r--r--indra/newview/skins/default/xui/pl/menu_viewer.xml68
-rw-r--r--indra/newview/skins/default/xui/pl/notifications.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about.xml30
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about_land.xml17
-rw-r--r--indra/newview/skins/default/xui/pt/floater_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_camera.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_hardware_settings.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_model_preview.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/floater_model_wizard.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/floater_moveview.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_snapshot.xml122
-rw-r--r--indra/newview/skins/default/xui/pt/floater_toybox.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/floater_translation_settings.xml58
-rw-r--r--indra/newview/skins/default/xui/pt/floater_voice_controls.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/menu_toolbars.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/menu_viewer.xml86
-rw-r--r--indra/newview/skins/default/xui/pt/notifications.xml42
-rw-r--r--indra/newview/skins/default/xui/pt/panel_edit_skin.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/panel_postcard_message.xml21
-rw-r--r--indra/newview/skins/default/xui/pt/panel_postcard_settings.xml23
-rw-r--r--indra/newview/skins/default/xui/pt/panel_preferences_chat.xml27
-rw-r--r--indra/newview/skins/default/xui/pt/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml21
-rw-r--r--indra/newview/skins/default/xui/pt/panel_snapshot_local.xml39
-rw-r--r--indra/newview/skins/default/xui/pt/panel_snapshot_options.xml7
-rw-r--r--indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml17
-rw-r--r--indra/newview/skins/default/xui/pt/panel_snapshot_profile.xml28
-rw-r--r--indra/newview/skins/default/xui/pt/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml61
-rw-r--r--indra/newview/skins/default/xui/pt/teleport_strings.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/floater_about.xml46
-rw-r--r--indra/newview/skins/default/xui/ru/floater_about_land.xml17
-rw-r--r--indra/newview/skins/default/xui/ru/floater_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_camera.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_hardware_settings.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_model_preview.xml5
-rw-r--r--indra/newview/skins/default/xui/ru/floater_model_wizard.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/floater_moveview.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_snapshot.xml121
-rw-r--r--indra/newview/skins/default/xui/ru/floater_toybox.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/floater_translation_settings.xml58
-rw-r--r--indra/newview/skins/default/xui/ru/floater_voice_controls.xml8
-rw-r--r--indra/newview/skins/default/xui/ru/menu_toolbars.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/menu_viewer.xml54
-rw-r--r--indra/newview/skins/default/xui/ru/notifications.xml40
-rw-r--r--indra/newview/skins/default/xui/ru/panel_edit_skin.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/panel_nearby_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_postcard_message.xml21
-rw-r--r--indra/newview/skins/default/xui/ru/panel_postcard_settings.xml23
-rw-r--r--indra/newview/skins/default/xui/ru/panel_preferences_chat.xml26
-rw-r--r--indra/newview/skins/default/xui/ru/panel_preferences_general.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml21
-rw-r--r--indra/newview/skins/default/xui/ru/panel_snapshot_local.xml39
-rw-r--r--indra/newview/skins/default/xui/ru/panel_snapshot_options.xml7
-rw-r--r--indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml17
-rw-r--r--indra/newview/skins/default/xui/ru/panel_snapshot_profile.xml28
-rw-r--r--indra/newview/skins/default/xui/ru/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml59
-rw-r--r--indra/newview/skins/default/xui/ru/teleport_strings.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/floater_about.xml48
-rw-r--r--indra/newview/skins/default/xui/tr/floater_about_land.xml17
-rw-r--r--indra/newview/skins/default/xui/tr/floater_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_camera.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_hardware_settings.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/floater_model_preview.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/floater_model_wizard.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/floater_moveview.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_snapshot.xml121
-rw-r--r--indra/newview/skins/default/xui/tr/floater_toybox.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/floater_translation_settings.xml58
-rw-r--r--indra/newview/skins/default/xui/tr/floater_voice_controls.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/menu_toolbars.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/menu_viewer.xml58
-rw-r--r--indra/newview/skins/default/xui/tr/notifications.xml40
-rw-r--r--indra/newview/skins/default/xui/tr/panel_edit_skin.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/panel_postcard_message.xml21
-rw-r--r--indra/newview/skins/default/xui/tr/panel_postcard_settings.xml23
-rw-r--r--indra/newview/skins/default/xui/tr/panel_preferences_chat.xml26
-rw-r--r--indra/newview/skins/default/xui/tr/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml21
-rw-r--r--indra/newview/skins/default/xui/tr/panel_snapshot_local.xml39
-rw-r--r--indra/newview/skins/default/xui/tr/panel_snapshot_options.xml7
-rw-r--r--indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml17
-rw-r--r--indra/newview/skins/default/xui/tr/panel_snapshot_profile.xml28
-rw-r--r--indra/newview/skins/default/xui/tr/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml61
-rw-r--r--indra/newview/skins/default/xui/tr/teleport_strings.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/menu_viewer.xml70
-rw-r--r--indra/newview/skins/default/xui/zh/notifications.xml2
-rw-r--r--indra/newview/skins/paths.xml2
-rw-r--r--indra/newview/viewer_manifest.py42
-rw-r--r--indra/test/catch_and_store_what_in.h86
-rw-r--r--indra/test/llevents_tut.cpp78
-rw-r--r--indra/test/manageapr.h46
-rw-r--r--indra/test/namedtempfile.h114
-rw-r--r--indra/test/test.cpp191
-rw-r--r--indra/viewer_components/updater/llupdatedownloader.cpp23
-rw-r--r--indra/viewer_components/updater/llupdateinstaller.cpp20
557 files changed, 15214 insertions, 6853 deletions
diff --git a/.hgtags b/.hgtags
index d8ece0c865..2701d2bab0 100644
--- a/.hgtags
+++ b/.hgtags
@@ -228,6 +228,10 @@ c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
+a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release
+fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
+a9abb9633a266c8d2fe62411cfd1c86d32da72bf 2.7.1-release
+fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start
a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release
fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
@@ -240,3 +244,19 @@ fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
bd6bcde2584491fd9228f1fa51c4575f4e764e19 DRTVWR-103_3.2.4-release
bd6bcde2584491fd9228f1fa51c4575f4e764e19 3.2.4-release
+3d2d5d244c6398a4214c666d5dd3965b0918709a DRTVWR-106_3.2.5-beta1
+3d2d5d244c6398a4214c666d5dd3965b0918709a 3.2.5-beta1
+65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d DRTVWR-107_3.2.5-beta2
+65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d 3.2.5-beta2
+c6175c955a19e9b9353d242889ec1779b5762522 DRTVWR-105_3.2.5-release
+c6175c955a19e9b9353d242889ec1779b5762522 3.2.5-release
+2174ed1c7129562428a5cfe8651ed77b8d26ae18 3.2.6-start
+286d73ff5c19f6c00e023dc1b60975ed6bbe2872 DRTVWR-109_3.2.6-beta1
+4891c46a56fed7512c783b9cbe7cb7260727bf0c 3.2.7-start
+286d73ff5c19f6c00e023dc1b60975ed6bbe2872 3.2.6-beta1
+c6175c955a19e9b9353d242889ec1779b5762522 DRTVWR-105_3.2.5-release
+c6175c955a19e9b9353d242889ec1779b5762522 3.2.5-release
+3d75c836d178c7c7e788f256afe195f6cab764a2 DRTVWR-111_3.2.7-beta1
+3d75c836d178c7c7e788f256afe195f6cab764a2 3.2.7-beta1
+89980333c99dbaf1787fe20784f1d8849e9b5d4f 3.2.8-start
+37dd400ad721e2a89ee820ffc1e7e433c68f3ca2 3.2.9-start
diff --git a/autobuild.xml b/autobuild.xml
index 9914be6867..99fa201ee3 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -90,9 +90,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>9868bfa0b6954e4884c49c6f30068c80</string>
+ <string>15333927db9f249daefcaed70fc6683c</string>
<key>url</key>
- <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.4.2-darwin-20110217.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-apr/rev/249247/arch/Darwin/installer/apr_suite-1.4.5-darwin-20120210.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -102,9 +102,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>ff62946c518a247c86e1066c1e9a5855</string>
+ <string>297508ece8b0f334bae842fd147f2962</string>
<key>url</key>
- <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.4.2-linux-20110309.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-apr/rev/249247/arch/Linux/installer/apr_suite-1.4.5-linux-20120211.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@@ -114,9 +114,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>73785c200a5b4ef74a1230b028bb680d</string>
+ <string>7ad1e767f4419a6d35a70abba1edbcdc</string>
<key>url</key>
- <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.4.2-windows-20110217.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-apr/rev/249247/arch/CYGWIN/installer/apr_suite-1.4.5-windows-20120210.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 1a3fc680bc..c5db396c97 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -485,6 +485,7 @@ Ima Mechanique
OPEN-76
STORM-959
STORM-1175
+ STORM-1708
Imnotgoing Sideways
Inma Rau
Innula Zenovka
@@ -594,6 +595,8 @@ Jonathan Yap
STORM-1674
STORM-1685
STORM-1721
+ STORM-1727
+ STORM-1725
STORM-1719
STORM-1712
STORM-1728
@@ -603,6 +606,10 @@ Jonathan Yap
STORM-653
STORM-1737
STORM-1733
+ STORM-1790
+ STORM-1788
+ STORM-1799
+ STORM-1796
Kadah Coba
STORM-1060
Jondan Lundquist
@@ -1254,6 +1261,7 @@ Zi Ree
VWR-1140
VWR-24017
VWR-25588
+ STORM-1790
Zipherius Turas
VWR-76
VWR-77
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 4b1bf49d07..1cebb53a07 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -66,7 +66,6 @@ if (VIEWER)
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
- add_subdirectory(${LIBS_OPEN_PREFIX}llxuixml)
add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
# Legacy C++ tests. Build always, run if LL_TESTS is true.
diff --git a/indra/cmake/LLTestCommand.cmake b/indra/cmake/LLTestCommand.cmake
index b5a0580a90..f75c23a5de 100644
--- a/indra/cmake/LLTestCommand.cmake
+++ b/indra/cmake/LLTestCommand.cmake
@@ -9,6 +9,9 @@ MACRO(LL_TEST_COMMAND OUTVAR LD_LIBRARY_PATH)
FOREACH(dir ${LD_LIBRARY_PATH})
LIST(APPEND value "-l${dir}")
ENDFOREACH(dir)
+ # Enough different tests want to be able to find CMake's PYTHON_EXECUTABLE
+ # that we should just pop it into the environment for everybody.
+ LIST(APPEND value "-DPYTHON=${PYTHON_EXECUTABLE}")
LIST(APPEND value ${ARGN})
SET(${OUTVAR} ${value})
##IF(LL_TEST_VERBOSE)
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index 1180460f4b..633ad84159 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -18,7 +18,6 @@ include(LLWindow)
include(LLUI)
include(LLVFS) # ugh, needed for LLDir
include(LLXML)
-include(LLXUIXML)
include(Linking)
# include(Tut)
@@ -32,7 +31,6 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
- ${LLXUIXML_INCLUDE_DIRS}
)
set(llui_libtest_SOURCE_FILES
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index c33a03034a..a4fb77357c 100644
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -41,6 +41,14 @@ import tarfile
import errno
import subprocess
+class ManifestError(RuntimeError):
+ """Use an exception more specific than generic Python RuntimeError"""
+ pass
+
+class MissingError(ManifestError):
+ """You specified a file that doesn't exist"""
+ pass
+
def path_ancestors(path):
drive, path = os.path.splitdrive(os.path.normpath(path))
result = []
@@ -180,6 +188,9 @@ def usage(srctree=""):
arg['description'] % nd)
def main():
+## import itertools
+## print ' '.join((("'%s'" % item) if ' ' in item else item)
+## for item in itertools.chain([sys.executable], sys.argv))
option_names = [arg['name'] + '=' for arg in ARGUMENTS]
option_names.append('help')
options, remainder = getopt.getopt(sys.argv[1:], "", option_names)
@@ -385,7 +396,7 @@ class LLManifest(object):
child.stdout.close()
status = child.wait()
if status:
- raise RuntimeError(
+ raise ManifestError(
"Command %s returned non-zero status (%s) \noutput:\n%s"
% (command, status, output) )
return output
@@ -395,7 +406,7 @@ class LLManifest(object):
a) verify that you really have created it
b) schedule it for cleanup"""
if not os.path.exists(path):
- raise RuntimeError, "Should be something at path " + path
+ raise ManifestError, "Should be something at path " + path
self.created_paths.append(path)
def put_in_file(self, contents, dst):
@@ -550,7 +561,7 @@ class LLManifest(object):
except (IOError, os.error), why:
errors.append((srcname, dstname, why))
if errors:
- raise RuntimeError, errors
+ raise ManifestError, errors
def cmakedirs(self, path):
@@ -598,11 +609,10 @@ class LLManifest(object):
def check_file_exists(self, path):
if not os.path.exists(path) and not os.path.islink(path):
- raise RuntimeError("Path %s doesn't exist" % (
- os.path.normpath(os.path.join(os.getcwd(), path)),))
+ raise MissingError("Path %s doesn't exist" % (os.path.abspath(path),))
- wildcard_pattern = re.compile('\*')
+ wildcard_pattern = re.compile(r'\*')
def expand_globs(self, src, dst):
src_list = glob.glob(src)
src_re, d_template = self.wildcard_regex(src.replace('\\', '/'),
@@ -615,7 +625,7 @@ class LLManifest(object):
sys.stdout.write("Processing %s => %s ... " % (src, dst))
sys.stdout.flush()
if src == None:
- raise RuntimeError("No source file, dst is " + dst)
+ raise ManifestError("No source file, dst is " + dst)
if dst == None:
dst = src
dst = os.path.join(self.get_dst_prefix(), dst)
@@ -637,13 +647,23 @@ class LLManifest(object):
else:
count += self.process_file(src, dst)
return count
- try:
- count = try_path(os.path.join(self.get_src_prefix(), src))
- except RuntimeError:
+
+ for pfx in self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix():
try:
- count = try_path(os.path.join(self.get_artwork_prefix(), src))
- except RuntimeError:
- count = try_path(os.path.join(self.get_build_prefix(), src))
+ count = try_path(os.path.join(pfx, src))
+ except MissingError:
+ # If src isn't a wildcard, and if that file doesn't exist in
+ # this pfx, try next pfx.
+ count = 0
+ continue
+
+ # Here try_path() didn't raise MissingError. Did it process any files?
+ if count:
+ break
+ # Even though try_path() didn't raise MissingError, it returned 0
+ # files. src is probably a wildcard meant for some other pfx. Loop
+ # back to try the next.
+
print "%d files" % count
def do(self, *actions):
diff --git a/indra/linux_updater/CMakeLists.txt b/indra/linux_updater/CMakeLists.txt
index 00a78b2a8f..4377a6333c 100644
--- a/indra/linux_updater/CMakeLists.txt
+++ b/indra/linux_updater/CMakeLists.txt
@@ -10,14 +10,14 @@ include(UI)
include(LLCommon)
include(LLVFS)
include(LLXML)
-include(LLXUIXML)
+include(LLUI)
include(Linking)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
- ${LLXUIXML_INCLUDE_DIRS}
+ ${LLUI_INCLUDE_DIRS}
${CURL_INCLUDE_DIRS}
${CARES_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
@@ -42,7 +42,7 @@ target_link_libraries(linux-updater
${CRYPTO_LIBRARIES}
${UI_LIBRARIES}
${LLXML_LIBRARIES}
- ${LLXUIXML_LIBRARIES}
+ ${LLUI_LIBRARIES}
${LLVFS_LIBRARIES}
${LLCOMMON_LIBRARIES}
)
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index 5e540ad8c5..5fa28cb902 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -1264,6 +1264,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32
mSyncSlave(false),
mQueueSounds(false),
mPlayedOnce(false),
+ mCorrupted(false),
mType(type),
mChannelp(NULL),
mCurrentDatap(NULL),
@@ -1296,16 +1297,25 @@ void LLAudioSource::setChannel(LLAudioChannel *channelp)
void LLAudioSource::update()
{
+ if(mCorrupted)
+ {
+ return ; //no need to update
+ }
+
if (!getCurrentBuffer())
{
if (getCurrentData())
{
// Hack - try and load the sound. Will do this as a callback
// on decode later.
- if (getCurrentData()->load())
+ if (getCurrentData()->load() && getCurrentData()->getBuffer())
{
play(getCurrentData()->getID());
- }
+ }
+ else
+ {
+ mCorrupted = true ;
+ }
}
}
}
@@ -1421,6 +1431,11 @@ bool LLAudioSource::play(const LLUUID &audio_uuid)
bool LLAudioSource::isDone() const
{
+ if(mCorrupted)
+ {
+ return true ;
+ }
+
const F32 MAX_AGE = 60.f;
const F32 MAX_UNPLAYED_AGE = 15.f;
const F32 MAX_MUTED_AGE = 11.f;
@@ -1736,7 +1751,7 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
}
}
-
+//return false when the audio file is corrupted.
bool LLAudioData::load()
{
// For now, just assume we're going to use one buffer per audiodata.
@@ -1752,7 +1767,7 @@ bool LLAudioData::load()
{
// No free buffers, abort.
llinfos << "Not able to allocate a new audio buffer, aborting." << llendl;
- return false;
+ return true;
}
std::string uuid_str;
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index 30d2490635..a47ee7ca7c 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -334,6 +334,7 @@ protected:
bool mSyncSlave;
bool mQueueSounds;
bool mPlayedOnce;
+ bool mCorrupted;
S32 mType;
LLVector3d mPositionGlobal;
LLVector3 mVelocity;
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 0a3eaec5c5..1cab648cfa 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -61,6 +61,7 @@ set(llcommon_SOURCE_FILES
llformat.cpp
llframetimer.cpp
llheartbeat.cpp
+ llinitparam.cpp
llinstancetracker.cpp
llliveappconfig.cpp
lllivefile.cpp
@@ -74,13 +75,14 @@ set(llcommon_SOURCE_FILES
llmortician.cpp
lloptioninterface.cpp
llptrto.cpp
- llprocesslauncher.cpp
+ llprocess.cpp
llprocessor.cpp
llqueuedthread.cpp
llrand.cpp
llrefcount.cpp
llrun.cpp
llsd.cpp
+ llsdparam.cpp
llsdserialize.cpp
llsdserialize_xml.cpp
llsdutil.cpp
@@ -88,6 +90,7 @@ set(llcommon_SOURCE_FILES
llsingleton.cpp
llstat.cpp
llstacktrace.cpp
+ llstreamqueue.cpp
llstreamtools.cpp
llstring.cpp
llstringtable.cpp
@@ -173,6 +176,7 @@ set(llcommon_HEADER_FILES
llheartbeat.h
llhttpstatuscodes.h
llindexedqueue.h
+ llinitparam.h
llinstancetracker.h
llkeythrottle.h
lllazy.h
@@ -196,7 +200,7 @@ set(llcommon_HEADER_FILES
llpointer.h
llpreprocessor.h
llpriqueuemap.h
- llprocesslauncher.h
+ llprocess.h
llprocessor.h
llptrskiplist.h
llptrskipmap.h
@@ -204,10 +208,12 @@ set(llcommon_HEADER_FILES
llqueuedthread.h
llrand.h
llrefcount.h
+ llregistry.h
llrun.h
llrefcount.h
llsafehandle.h
llsd.h
+ llsdparam.h
llsdserialize.h
llsdserialize_xml.h
llsdutil.h
@@ -221,6 +227,7 @@ set(llcommon_HEADER_FILES
llstat.h
llstatenums.h
llstl.h
+ llstreamqueue.h
llstreamtools.h
llstrider.h
llstring.h
@@ -317,8 +324,7 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}"
- "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/setpython.py")
+ LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
@@ -326,6 +332,8 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(reflection "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}")
# *TODO - reenable these once tcmalloc libs no longer break the build.
#ADD_BUILD_TEST(llallocator llcommon)
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index c35799bbb9..e4381dbbd6 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -617,6 +617,12 @@ namespace LLError
s.defaultLevel = level;
}
+ ELevel getDefaultLevel()
+ {
+ Settings& s = Settings::get();
+ return s.defaultLevel;
+ }
+
void setFunctionLevel(const std::string& function_name, ELevel level)
{
Globals& g = Globals::get();
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index fb75d45e2c..ed9de002f5 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -75,6 +75,7 @@ namespace LLError
LL_COMMON_API void setPrintLocation(bool);
LL_COMMON_API void setDefaultLevel(LLError::ELevel);
+ LL_COMMON_API ELevel getDefaultLevel();
LL_COMMON_API void setFunctionLevel(const std::string& function_name, LLError::ELevel);
LL_COMMON_API void setClassLevel(const std::string& class_name, LLError::ELevel);
LL_COMMON_API void setFileLevel(const std::string& file_name, LLError::ELevel);
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index db72aa19b9..db72aa19b9 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
diff --git a/indra/llxuixml/llinitparam.h b/indra/llcommon/llinitparam.h
index ab20957760..beaf07e56b 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -205,7 +205,7 @@ namespace LLInitParam
mutable std::string mValueName;
};
- class Parser
+ class LL_COMMON_API Parser
{
LOG_CLASS(Parser);
@@ -301,7 +301,7 @@ namespace LLInitParam
class Param;
// various callbacks and constraints associated with an individual param
- struct ParamDescriptor
+ struct LL_COMMON_API ParamDescriptor
{
struct UserData
{
@@ -341,7 +341,7 @@ namespace LLInitParam
typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;
// each derived Block class keeps a static data structure maintaining offsets to various params
- class BlockDescriptor
+ class LL_COMMON_API BlockDescriptor
{
public:
BlockDescriptor();
@@ -369,7 +369,7 @@ namespace LLInitParam
class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
};
- class BaseBlock
+ class LL_COMMON_API BaseBlock
{
public:
//TODO: implement in terms of owned_ptr
@@ -566,7 +566,7 @@ namespace LLInitParam
static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); }
};
- class Param
+ class LL_COMMON_API Param
{
public:
void setProvided(bool is_provided = true)
@@ -2057,8 +2057,8 @@ namespace LLInitParam
// block param interface
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
+ LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
+ LL_COMMON_API void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
{
//TODO: implement LLSD params as schema type Any
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 34d841a4e0..403df08990 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -167,8 +167,9 @@ public:
static T* getInstance(const KEY& k)
{
- typename InstanceMap::const_iterator found = getMap_().find(k);
- return (found == getMap_().end()) ? NULL : found->second;
+ const InstanceMap& map(getMap_());
+ typename InstanceMap::const_iterator found = map.find(k);
+ return (found == map.end()) ? NULL : found->second;
}
static instance_iter beginInstances()
@@ -239,8 +240,20 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
public:
- /// for completeness of analogy with the generic implementation
- static T* getInstance(T* k) { return k; }
+ /**
+ * Does a particular instance still exist? Of course, if you already have
+ * a T* in hand, you need not call getInstance() to @em locate the
+ * instance -- unlike the case where getInstance() accepts some kind of
+ * key. Nonetheless this method is still useful to @em validate a
+ * particular T*, since each instance's destructor removes itself from the
+ * underlying set.
+ */
+ static T* getInstance(T* k)
+ {
+ const InstanceSet& set(getSet_());
+ typename InstanceSet::const_iterator found = set.find(k);
+ return (found == set.end())? NULL : *found;
+ }
static S32 instanceCount() { return getSet_().size(); }
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp
new file mode 100644
index 0000000000..3b17b819bd
--- /dev/null
+++ b/indra/llcommon/llprocess.cpp
@@ -0,0 +1,1189 @@
+/**
+ * @file llprocess.cpp
+ * @brief Utility class for launching, terminating, and tracking the state of processes.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llprocess.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+#include "llsingleton.h"
+#include "llstring.h"
+#include "stringize.h"
+#include "llapr.h"
+#include "apr_signal.h"
+#include "llevents.h"
+
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <boost/asio/streambuf.hpp>
+#include <boost/asio/buffers_iterator.hpp>
+#include <iostream>
+#include <stdexcept>
+#include <limits>
+#include <algorithm>
+#include <vector>
+#include <typeinfo>
+#include <utility>
+
+static const char* whichfile_[] = { "stdin", "stdout", "stderr" };
+static std::string empty;
+static LLProcess::Status interpret_status(int status);
+static std::string getDesc(const LLProcess::Params& params);
+
+static std::string whichfile(LLProcess::FILESLOT index)
+{
+ if (index < LL_ARRAY_SIZE(whichfile_))
+ return whichfile_[index];
+ return STRINGIZE("file slot " << index);
+}
+
+/**
+ * Ref-counted "mainloop" listener. As long as there are still outstanding
+ * LLProcess objects, keep listening on "mainloop" so we can keep polling APR
+ * for process status.
+ */
+class LLProcessListener
+{
+ LOG_CLASS(LLProcessListener);
+public:
+ LLProcessListener():
+ mCount(0)
+ {}
+
+ void addPoll(const LLProcess&)
+ {
+ // Unconditionally increment mCount. If it was zero before
+ // incrementing, listen on "mainloop".
+ if (mCount++ == 0)
+ {
+ LL_DEBUGS("LLProcess") << "listening on \"mainloop\"" << LL_ENDL;
+ mConnection = LLEventPumps::instance().obtain("mainloop")
+ .listen("LLProcessListener", boost::bind(&LLProcessListener::tick, this, _1));
+ }
+ }
+
+ void dropPoll(const LLProcess&)
+ {
+ // Unconditionally decrement mCount. If it's zero after decrementing,
+ // stop listening on "mainloop".
+ if (--mCount == 0)
+ {
+ LL_DEBUGS("LLProcess") << "disconnecting from \"mainloop\"" << LL_ENDL;
+ mConnection.disconnect();
+ }
+ }
+
+private:
+ /// called once per frame by the "mainloop" LLEventPump
+ bool tick(const LLSD&)
+ {
+ // Tell APR to sense whether each registered LLProcess is still
+ // running and call handle_status() appropriately. We should be able
+ // to get the same info from an apr_proc_wait(APR_NOWAIT) call; but at
+ // least in APR 1.4.2, testing suggests that even with APR_NOWAIT,
+ // apr_proc_wait() blocks the caller. We can't have that in the
+ // viewer. Hence the callback rigmarole. (Once we update APR, it's
+ // probably worth testing again.) Also -- although there's an
+ // apr_proc_other_child_refresh() call, i.e. get that information for
+ // one specific child, it accepts an 'apr_other_child_rec_t*' that's
+ // mentioned NOWHERE else in the documentation or header files! I
+ // would use the specific call in LLProcess::getStatus() if I knew
+ // how. As it is, each call to apr_proc_other_child_refresh_all() will
+ // call callbacks for ALL still-running child processes. That's why we
+ // centralize such calls, using "mainloop" to ensure it happens once
+ // per frame, and refcounting running LLProcess objects to remain
+ // registered only while needed.
+ LL_DEBUGS("LLProcess") << "calling apr_proc_other_child_refresh_all()" << LL_ENDL;
+ apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING);
+ return false;
+ }
+
+ /// If this object is destroyed before mCount goes to zero, stop
+ /// listening on "mainloop" anyway.
+ LLTempBoundListener mConnection;
+ unsigned mCount;
+};
+static LLProcessListener sProcessListener;
+
+LLProcess::BasePipe::~BasePipe() {}
+const LLProcess::BasePipe::size_type
+ // use funky syntax to call max() to avoid blighted max() macros
+ LLProcess::BasePipe::npos((std::numeric_limits<LLProcess::BasePipe::size_type>::max)());
+
+class WritePipeImpl: public LLProcess::WritePipe
+{
+ LOG_CLASS(WritePipeImpl);
+public:
+ WritePipeImpl(const std::string& desc, apr_file_t* pipe):
+ mDesc(desc),
+ mPipe(pipe),
+ // Essential to initialize our std::ostream with our special streambuf!
+ mStream(&mStreambuf)
+ {
+ mConnection = LLEventPumps::instance().obtain("mainloop")
+ .listen(LLEventPump::inventName("WritePipe"),
+ boost::bind(&WritePipeImpl::tick, this, _1));
+ }
+
+ virtual std::ostream& get_ostream() { return mStream; }
+
+ bool tick(const LLSD&)
+ {
+ typedef boost::asio::streambuf::const_buffers_type const_buffer_sequence;
+ // If there's anything to send, try to send it.
+ std::size_t total(mStreambuf.size()), consumed(0);
+ if (total)
+ {
+ const_buffer_sequence bufs = mStreambuf.data();
+ // In general, our streambuf might contain a number of different
+ // physical buffers; iterate over those.
+ for (const_buffer_sequence::const_iterator bufi(bufs.begin()), bufend(bufs.end());
+ bufi != bufend; ++bufi)
+ {
+ // http://www.boost.org/doc/libs/1_49_0_beta1/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.accessing_buffer_contents
+ std::size_t towrite(boost::asio::buffer_size(*bufi));
+ apr_size_t written(towrite);
+ apr_status_t err = apr_file_write(mPipe,
+ boost::asio::buffer_cast<const void*>(*bufi),
+ &written);
+ // EAGAIN is exactly what we want from a nonblocking pipe.
+ // Rather than waiting for data, it should return immediately.
+ if (! (err == APR_SUCCESS || APR_STATUS_IS_EAGAIN(err)))
+ {
+ LL_WARNS("LLProcess") << "apr_file_write(" << towrite << ") on " << mDesc
+ << " got " << err << ":" << LL_ENDL;
+ ll_apr_warn_status(err);
+ }
+
+ // 'written' is modified to reflect the number of bytes actually
+ // written. Make sure we consume those later. (Don't consume them
+ // now, that would invalidate the buffer iterator sequence!)
+ consumed += written;
+ LL_DEBUGS("LLProcess") << "wrote " << written << " of " << towrite
+ << " bytes to " << mDesc
+ << " (original " << total << ")" << LL_ENDL;
+
+ // The parent end of this pipe is nonblocking. If we weren't able
+ // to write everything we wanted, don't keep banging on it -- that
+ // won't change until the child reads some. Wait for next tick().
+ if (written < towrite)
+ break;
+ }
+ // In all, we managed to write 'consumed' bytes. Remove them from the
+ // streambuf so we don't keep trying to send them. This could be
+ // anywhere from 0 up to mStreambuf.size(); anything we haven't yet
+ // sent, we'll try again later.
+ mStreambuf.consume(consumed);
+ }
+
+ return false;
+ }
+
+private:
+ std::string mDesc;
+ apr_file_t* mPipe;
+ LLTempBoundListener mConnection;
+ boost::asio::streambuf mStreambuf;
+ std::ostream mStream;
+};
+
+class ReadPipeImpl: public LLProcess::ReadPipe
+{
+ LOG_CLASS(ReadPipeImpl);
+public:
+ ReadPipeImpl(const std::string& desc, apr_file_t* pipe, LLProcess::FILESLOT index):
+ mDesc(desc),
+ mPipe(pipe),
+ mIndex(index),
+ // Essential to initialize our std::istream with our special streambuf!
+ mStream(&mStreambuf),
+ mPump("ReadPipe", true), // tweak name as needed to avoid collisions
+ mLimit(0)
+ {
+ mConnection = LLEventPumps::instance().obtain("mainloop")
+ .listen(LLEventPump::inventName("ReadPipe"),
+ boost::bind(&ReadPipeImpl::tick, this, _1));
+ }
+
+ // Much of the implementation is simply connecting the abstract virtual
+ // methods with implementation data concealed from the base class.
+ virtual std::istream& get_istream() { return mStream; }
+ virtual LLEventPump& getPump() { return mPump; }
+ virtual void setLimit(size_type limit) { mLimit = limit; }
+ virtual size_type getLimit() const { return mLimit; }
+ virtual size_type size() const { return mStreambuf.size(); }
+
+ virtual std::string peek(size_type offset=0, size_type len=npos) const
+ {
+ // Constrain caller's offset and len to overlap actual buffer content.
+ std::size_t real_offset = (std::min)(mStreambuf.size(), std::size_t(offset));
+ size_type want_end = (len == npos)? npos : (real_offset + len);
+ std::size_t real_end = (std::min)(mStreambuf.size(), std::size_t(want_end));
+ boost::asio::streambuf::const_buffers_type cbufs = mStreambuf.data();
+ return std::string(boost::asio::buffers_begin(cbufs) + real_offset,
+ boost::asio::buffers_begin(cbufs) + real_end);
+ }
+
+ virtual size_type find(const std::string& seek, size_type offset=0) const
+ {
+ // If we're passing a string of length 1, use find(char), which can
+ // use an O(n) std::find() rather than the O(n^2) std::search().
+ if (seek.length() == 1)
+ {
+ return find(seek[0], offset);
+ }
+
+ // If offset is beyond the whole buffer, can't even construct a valid
+ // iterator range; can't possibly find the string we seek.
+ if (offset > mStreambuf.size())
+ {
+ return npos;
+ }
+
+ boost::asio::streambuf::const_buffers_type cbufs = mStreambuf.data();
+ boost::asio::buffers_iterator<boost::asio::streambuf::const_buffers_type>
+ begin(boost::asio::buffers_begin(cbufs)),
+ end (boost::asio::buffers_end(cbufs)),
+ found(std::search(begin + offset, end, seek.begin(), seek.end()));
+ return (found == end)? npos : (found - begin);
+ }
+
+ virtual size_type find(char seek, size_type offset=0) const
+ {
+ // If offset is beyond the whole buffer, can't even construct a valid
+ // iterator range; can't possibly find the char we seek.
+ if (offset > mStreambuf.size())
+ {
+ return npos;
+ }
+
+ boost::asio::streambuf::const_buffers_type cbufs = mStreambuf.data();
+ boost::asio::buffers_iterator<boost::asio::streambuf::const_buffers_type>
+ begin(boost::asio::buffers_begin(cbufs)),
+ end (boost::asio::buffers_end(cbufs)),
+ found(std::find(begin + offset, end, seek));
+ return (found == end)? npos : (found - begin);
+ }
+
+private:
+ bool tick(const LLSD&)
+ {
+ typedef boost::asio::streambuf::mutable_buffers_type mutable_buffer_sequence;
+ // Try, every time, to read into our streambuf. In fact, we have no
+ // idea how much data the child might be trying to send: keep trying
+ // until we're convinced we've temporarily exhausted the pipe.
+ bool exhausted = false;
+ std::size_t committed(0);
+ do
+ {
+ // attempt to read an arbitrary size
+ mutable_buffer_sequence bufs = mStreambuf.prepare(4096);
+ // In general, the mutable_buffer_sequence returned by prepare() might
+ // contain a number of different physical buffers; iterate over those.
+ std::size_t tocommit(0);
+ for (mutable_buffer_sequence::const_iterator bufi(bufs.begin()), bufend(bufs.end());
+ bufi != bufend; ++bufi)
+ {
+ // http://www.boost.org/doc/libs/1_49_0_beta1/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.accessing_buffer_contents
+ std::size_t toread(boost::asio::buffer_size(*bufi));
+ apr_size_t gotten(toread);
+ apr_status_t err = apr_file_read(mPipe,
+ boost::asio::buffer_cast<void*>(*bufi),
+ &gotten);
+ // EAGAIN is exactly what we want from a nonblocking pipe.
+ // Rather than waiting for data, it should return immediately.
+ if (! (err == APR_SUCCESS || APR_STATUS_IS_EAGAIN(err)))
+ {
+ // Handle EOF specially: it's part of normal-case processing.
+ if (err == APR_EOF)
+ {
+ LL_DEBUGS("LLProcess") << "EOF on " << mDesc << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("LLProcess") << "apr_file_read(" << toread << ") on " << mDesc
+ << " got " << err << ":" << LL_ENDL;
+ ll_apr_warn_status(err);
+ }
+ // Either way, though, we won't need any more tick() calls.
+ mConnection.disconnect();
+ exhausted = true; // also break outer retry loop
+ break;
+ }
+
+ // 'gotten' was modified to reflect the number of bytes actually
+ // received. Make sure we commit those later. (Don't commit them
+ // now, that would invalidate the buffer iterator sequence!)
+ tocommit += gotten;
+ LL_DEBUGS("LLProcess") << "read " << gotten << " of " << toread
+ << " bytes from " << mDesc << LL_ENDL;
+
+ // The parent end of this pipe is nonblocking. If we weren't even
+ // able to fill this buffer, don't loop to try to fill the next --
+ // that won't change until the child writes more. Wait for next
+ // tick().
+ if (gotten < toread)
+ {
+ // break outer retry loop too
+ exhausted = true;
+ break;
+ }
+ }
+
+ // Don't forget to "commit" the data!
+ mStreambuf.commit(tocommit);
+ committed += tocommit;
+
+ // 'exhausted' is set when we can't fill any one buffer of the
+ // mutable_buffer_sequence established by the current prepare()
+ // call -- whether due to error or not enough bytes. That is,
+ // 'exhausted' is still false when we've filled every physical
+ // buffer in the mutable_buffer_sequence. In that case, for all we
+ // know, the child might have still more data pending -- go for it!
+ } while (! exhausted);
+
+ if (committed)
+ {
+ // If we actually received new data, publish it on our LLEventPump
+ // as advertised. Constrain it by mLimit. But show listener the
+ // actual accumulated buffer size, regardless of mLimit.
+ size_type datasize((std::min)(mLimit, size_type(mStreambuf.size())));
+ mPump.post(LLSDMap
+ ("data", peek(0, datasize))
+ ("len", LLSD::Integer(mStreambuf.size()))
+ ("index", LLSD::Integer(mIndex))
+ ("name", whichfile(mIndex))
+ ("desc", mDesc));
+ }
+
+ return false;
+ }
+
+ std::string mDesc;
+ apr_file_t* mPipe;
+ LLProcess::FILESLOT mIndex;
+ LLTempBoundListener mConnection;
+ boost::asio::streambuf mStreambuf;
+ std::istream mStream;
+ LLEventStream mPump;
+ size_type mLimit;
+};
+
+/// Need an exception to avoid constructing an invalid LLProcess object, but
+/// internal use only
+struct LLProcessError: public std::runtime_error
+{
+ LLProcessError(const std::string& msg): std::runtime_error(msg) {}
+};
+
+LLProcessPtr LLProcess::create(const LLSDOrParams& params)
+{
+ try
+ {
+ return LLProcessPtr(new LLProcess(params));
+ }
+ catch (const LLProcessError& e)
+ {
+ LL_WARNS("LLProcess") << e.what() << LL_ENDL;
+
+ // If caller is requesting an event on process termination, send one
+ // indicating bad launch. This may prevent someone waiting forever for
+ // a termination post that can't arrive because the child never
+ // started.
+ if (params.postend.isProvided())
+ {
+ LLEventPumps::instance().obtain(params.postend)
+ .post(LLSDMap
+ // no "id"
+ ("desc", getDesc(params))
+ ("state", LLProcess::UNSTARTED)
+ // no "data"
+ ("string", e.what())
+ );
+ }
+
+ return LLProcessPtr();
+ }
+}
+
+/// Call an apr function returning apr_status_t. On failure, log warning and
+/// throw LLProcessError mentioning the function call that produced that
+/// result.
+#define chkapr(func) \
+ if (ll_apr_warn_status(func)) \
+ throw LLProcessError(#func " failed")
+
+LLProcess::LLProcess(const LLSDOrParams& params):
+ mAutokill(params.autokill),
+ mPipes(NSLOTS)
+{
+ // Hmm, when you construct a ptr_vector with a size, it merely reserves
+ // space, it doesn't actually make it that big. Explicitly make it bigger.
+ // Because of ptr_vector's odd semantics, have to push_back(0) the right
+ // number of times! resize() wants to default-construct new BasePipe
+ // instances, which fails because it's pure virtual. But because of the
+ // constructor call, these push_back() calls should require no new
+ // allocation.
+ for (size_t i = 0; i < mPipes.capacity(); ++i)
+ mPipes.push_back(0);
+
+ if (! params.validateBlock(true))
+ {
+ throw LLProcessError(STRINGIZE("not launched: failed parameter validation\n"
+ << LLSDNotationStreamer(params)));
+ }
+
+ mPostend = params.postend;
+
+ apr_procattr_t *procattr = NULL;
+ chkapr(apr_procattr_create(&procattr, gAPRPoolp));
+
+ // For which of stdin, stdout, stderr should we create a pipe to the
+ // child? In the viewer, there are only a couple viable
+ // apr_procattr_io_set() alternatives: inherit the viewer's own stdxxx
+ // handle (APR_NO_PIPE, e.g. for stdout, stderr), or create a pipe that's
+ // blocking on the child end but nonblocking at the viewer end
+ // (APR_CHILD_BLOCK).
+ // Other major options could include explicitly creating a single APR pipe
+ // and passing it as both stdout and stderr (apr_procattr_child_out_set(),
+ // apr_procattr_child_err_set()), or accepting a filename, opening it and
+ // passing that apr_file_t (simple <, >, 2> redirect emulation).
+ std::vector<apr_int32_t> select;
+ BOOST_FOREACH(const FileParam& fparam, params.files)
+ {
+ // Every iteration, we're going to append an item to 'select'. At the
+ // top of the loop, its size() is, in effect, an index. Use that to
+ // pick a string description for messages.
+ std::string which(whichfile(FILESLOT(select.size())));
+ if (fparam.type().empty()) // inherit our file descriptor
+ {
+ select.push_back(APR_NO_PIPE);
+ }
+ else if (fparam.type() == "pipe") // anonymous pipe
+ {
+ if (! fparam.name().empty())
+ {
+ LL_WARNS("LLProcess") << "For " << params.executable()
+ << ": internal names for reusing pipes ('"
+ << fparam.name() << "' for " << which
+ << ") are not yet supported -- creating distinct pipe"
+ << LL_ENDL;
+ }
+ // The viewer can't block for anything: the parent end MUST be
+ // nonblocking. As the APR documentation itself points out, it
+ // makes very little sense to set nonblocking I/O for the child
+ // end of a pipe: only a specially-written child could deal with
+ // that.
+ select.push_back(APR_CHILD_BLOCK);
+ }
+ else
+ {
+ throw LLProcessError(STRINGIZE("For " << params.executable()
+ << ": unsupported FileParam for " << which
+ << ": type='" << fparam.type()
+ << "', name='" << fparam.name() << "'"));
+ }
+ }
+ // By default, pass APR_NO_PIPE for unspecified slots.
+ while (select.size() < NSLOTS)
+ {
+ select.push_back(APR_NO_PIPE);
+ }
+ chkapr(apr_procattr_io_set(procattr, select[STDIN], select[STDOUT], select[STDERR]));
+
+ // Thumbs down on implicitly invoking the shell to invoke the child. From
+ // our point of view, the other major alternative to APR_PROGRAM_PATH
+ // would be APR_PROGRAM_ENV: still copy environment, but require full
+ // executable pathname. I don't see a downside to searching the PATH,
+ // though: if our caller wants (e.g.) a specific Python interpreter, s/he
+ // can still pass the full pathname.
+ chkapr(apr_procattr_cmdtype_set(procattr, APR_PROGRAM_PATH));
+ // YES, do extra work if necessary to report child exec() failures back to
+ // parent process.
+ chkapr(apr_procattr_error_check_set(procattr, 1));
+ // Do not start a non-autokill child in detached state. On Posix
+ // platforms, this setting attempts to daemonize the new child, closing
+ // std handles and the like, and that's a bit more detachment than we
+ // want. autokill=false just means not to implicitly kill the child when
+ // the parent terminates!
+// chkapr(apr_procattr_detach_set(procattr, params.autokill? 0 : 1));
+
+ if (params.autokill)
+ {
+#if defined(APR_HAS_PROCATTR_AUTOKILL_SET)
+ apr_status_t ok = apr_procattr_autokill_set(procattr, 1);
+# if LL_WINDOWS
+ // As of 2012-02-02, we only expect this to be implemented on Windows.
+ // Avoid spamming the log with warnings we fully expect.
+ ll_apr_warn_status(ok);
+#else // ! LL_WINDOWS
+ (void)ok; // suppress 'unused' warning
+# endif // ! LL_WINDOWS
+#else
+ LL_WARNS("LLProcess") << "This version of APR lacks Linden apr_procattr_autokill_set() extension" << LL_ENDL;
+#endif
+ }
+
+ // In preparation for calling apr_proc_create(), we collect a number of
+ // const char* pointers obtained from std::string::c_str(). Turns out
+ // LLInitParam::Block's helpers Optional, Mandatory, Multiple et al.
+ // guarantee that converting to the wrapped type (std::string in our
+ // case), e.g. by calling operator(), returns a reference to *the same
+ // instance* of the wrapped type that's stored in our Block subclass.
+ // That's important! We know 'params' persists throughout this method
+ // call; but without that guarantee, we'd have to assume that converting
+ // one of its members to std::string might return a different (temp)
+ // instance. Capturing the c_str() from a temporary std::string is Bad Bad
+ // Bad. But armed with this knowledge, when you see params.cwd().c_str(),
+ // grit your teeth and smile and carry on.
+
+ if (params.cwd.isProvided())
+ {
+ chkapr(apr_procattr_dir_set(procattr, params.cwd().c_str()));
+ }
+
+ // create an argv vector for the child process
+ std::vector<const char*> argv;
+
+ // Add the executable path. See above remarks about c_str().
+ argv.push_back(params.executable().c_str());
+
+ // Add arguments. See above remarks about c_str().
+ BOOST_FOREACH(const std::string& arg, params.args)
+ {
+ argv.push_back(arg.c_str());
+ }
+
+ // terminate with a null pointer
+ argv.push_back(NULL);
+
+ // Launch! The NULL would be the environment block, if we were passing one.
+ chkapr(apr_proc_create(&mProcess, argv[0], &argv[0], NULL, procattr, gAPRPoolp));
+
+ // arrange to call status_callback()
+ apr_proc_other_child_register(&mProcess, &LLProcess::status_callback, this, mProcess.in,
+ gAPRPoolp);
+ // and make sure we poll it once per "mainloop" tick
+ sProcessListener.addPoll(*this);
+ mStatus.mState = RUNNING;
+
+ mDesc = STRINGIZE(getDesc(params) << " (" << mProcess.pid << ')');
+ LL_INFOS("LLProcess") << mDesc << ": launched " << params << LL_ENDL;
+
+ // Unless caller explicitly turned off autokill (child should persist),
+ // take steps to terminate the child. This is all suspenders-and-belt: in
+ // theory our destructor should kill an autokill child, but in practice
+ // that doesn't always work (e.g. VWR-21538).
+ if (params.autokill)
+ {
+ // Tie the lifespan of this child process to the lifespan of our APR
+ // pool: on destruction of the pool, forcibly kill the process. Tell
+ // APR to try SIGTERM and wait 3 seconds. If that didn't work, use
+ // SIGKILL.
+ apr_pool_note_subprocess(gAPRPoolp, &mProcess, APR_KILL_AFTER_TIMEOUT);
+
+ // On Windows, associate the new child process with our Job Object.
+ autokill();
+ }
+
+ // Instantiate the proper pipe I/O machinery
+ // want to be able to point to apr_proc_t::in, out, err by index
+ typedef apr_file_t* apr_proc_t::*apr_proc_file_ptr;
+ static apr_proc_file_ptr members[] =
+ { &apr_proc_t::in, &apr_proc_t::out, &apr_proc_t::err };
+ for (size_t i = 0; i < NSLOTS; ++i)
+ {
+ if (select[i] != APR_CHILD_BLOCK)
+ continue;
+ std::string desc(STRINGIZE(mDesc << ' ' << whichfile(FILESLOT(i))));
+ apr_file_t* pipe(mProcess.*(members[i]));
+ if (i == STDIN)
+ {
+ mPipes.replace(i, new WritePipeImpl(desc, pipe));
+ }
+ else
+ {
+ mPipes.replace(i, new ReadPipeImpl(desc, pipe, FILESLOT(i)));
+ }
+ LL_DEBUGS("LLProcess") << "Instantiating " << typeid(mPipes[i]).name()
+ << "('" << desc << "')" << LL_ENDL;
+ }
+}
+
+// Helper to obtain a description string, given a Params block
+static std::string getDesc(const LLProcess::Params& params)
+{
+ // If caller specified a description string, by all means use it.
+ if (params.desc.isProvided())
+ return params.desc;
+
+ // Caller didn't say. Use the executable name -- but use just the filename
+ // part. On Mac, for instance, full pathnames get cumbersome.
+ // If there are Linden utility functions to manipulate pathnames, I
+ // haven't found them -- and for this usage, Boost.Filesystem seems kind
+ // of heavyweight.
+ std::string executable(params.executable);
+ std::string::size_type delim = executable.find_last_of("\\/");
+ // If executable contains no pathname delimiters, return the whole thing.
+ if (delim == std::string::npos)
+ return executable;
+
+ // Return just the part beyond the last delimiter.
+ return executable.substr(delim + 1);
+}
+
+LLProcess::~LLProcess()
+{
+ // Only in state RUNNING are we registered for callback. In UNSTARTED we
+ // haven't yet registered. And since receiving the callback is the only
+ // way we detect child termination, we only change from state RUNNING at
+ // the same time we unregister.
+ if (mStatus.mState == RUNNING)
+ {
+ // We're still registered for a callback: unregister. Do it before
+ // we even issue the kill(): even if kill() somehow prompted an
+ // instantaneous callback (unlikely), this object is going away! Any
+ // information updated in this object by such a callback is no longer
+ // available to any consumer anyway.
+ apr_proc_other_child_unregister(this);
+ // One less LLProcess to poll for
+ sProcessListener.dropPoll(*this);
+ }
+
+ if (mAutokill)
+ {
+ kill("destructor");
+ }
+}
+
+bool LLProcess::kill(const std::string& who)
+{
+ if (isRunning())
+ {
+ LL_INFOS("LLProcess") << who << " killing " << mDesc << LL_ENDL;
+
+#if LL_WINDOWS
+ int sig = -1;
+#else // Posix
+ int sig = SIGTERM;
+#endif
+
+ ll_apr_warn_status(apr_proc_kill(&mProcess, sig));
+ }
+
+ return ! isRunning();
+}
+
+bool LLProcess::isRunning() const
+{
+ return getStatus().mState == RUNNING;
+}
+
+LLProcess::Status LLProcess::getStatus() const
+{
+ return mStatus;
+}
+
+std::string LLProcess::getStatusString() const
+{
+ return getStatusString(getStatus());
+}
+
+std::string LLProcess::getStatusString(const Status& status) const
+{
+ return getStatusString(mDesc, status);
+}
+
+//static
+std::string LLProcess::getStatusString(const std::string& desc, const Status& status)
+{
+ if (status.mState == UNSTARTED)
+ return desc + " was never launched";
+
+ if (status.mState == RUNNING)
+ return desc + " running";
+
+ if (status.mState == EXITED)
+ return STRINGIZE(desc << " exited with code " << status.mData);
+
+ if (status.mState == KILLED)
+#if LL_WINDOWS
+ return STRINGIZE(desc << " killed with exception " << std::hex << status.mData);
+#else
+ return STRINGIZE(desc << " killed by signal " << status.mData
+ << " (" << apr_signal_description_get(status.mData) << ")");
+#endif
+
+ return STRINGIZE(desc << " in unknown state " << status.mState << " (" << status.mData << ")");
+}
+
+// Classic-C-style APR callback
+void LLProcess::status_callback(int reason, void* data, int status)
+{
+ // Our only role is to bounce this static method call back into object
+ // space.
+ static_cast<LLProcess*>(data)->handle_status(reason, status);
+}
+
+#define tabent(symbol) { symbol, #symbol }
+static struct ReasonCode
+{
+ int code;
+ const char* name;
+} reasons[] =
+{
+ tabent(APR_OC_REASON_DEATH),
+ tabent(APR_OC_REASON_UNWRITABLE),
+ tabent(APR_OC_REASON_RESTART),
+ tabent(APR_OC_REASON_UNREGISTER),
+ tabent(APR_OC_REASON_LOST),
+ tabent(APR_OC_REASON_RUNNING)
+};
+#undef tabent
+
+// Object-oriented callback
+void LLProcess::handle_status(int reason, int status)
+{
+ {
+ // This odd appearance of LL_DEBUGS is just to bracket a lookup that will
+ // only be performed if in fact we're going to produce the log message.
+ LL_DEBUGS("LLProcess") << empty;
+ std::string reason_str;
+ BOOST_FOREACH(const ReasonCode& rcp, reasons)
+ {
+ if (reason == rcp.code)
+ {
+ reason_str = rcp.name;
+ break;
+ }
+ }
+ if (reason_str.empty())
+ {
+ reason_str = STRINGIZE("unknown reason " << reason);
+ }
+ LL_CONT << mDesc << ": handle_status(" << reason_str << ", " << status << ")" << LL_ENDL;
+ }
+
+ if (! (reason == APR_OC_REASON_DEATH || reason == APR_OC_REASON_LOST))
+ {
+ // We're only interested in the call when the child terminates.
+ return;
+ }
+
+ // Somewhat oddly, APR requires that you explicitly unregister even when
+ // it already knows the child has terminated. We must pass the same 'data'
+ // pointer as for the register() call, which was our 'this'.
+ apr_proc_other_child_unregister(this);
+ // don't keep polling for a terminated process
+ sProcessListener.dropPoll(*this);
+ // We overload mStatus.mState to indicate whether the child is registered
+ // for APR callback: only RUNNING means registered. Track that we've
+ // unregistered. We know the child has terminated; might be EXITED or
+ // KILLED; refine below.
+ mStatus.mState = EXITED;
+
+// wi->rv = apr_proc_wait(wi->child, &wi->rc, &wi->why, APR_NOWAIT);
+ // It's just wrong to call apr_proc_wait() here. The only way APR knows to
+ // call us with APR_OC_REASON_DEATH is that it's already reaped this child
+ // process, so calling wait() will only produce "huh?" from the OS. We
+ // must rely on the status param passed in, which unfortunately comes
+ // straight from the OS wait() call, which means we have to decode it by
+ // hand.
+ mStatus = interpret_status(status);
+ LL_INFOS("LLProcess") << getStatusString() << LL_ENDL;
+
+ // If caller requested notification on child termination, send it.
+ if (! mPostend.empty())
+ {
+ LLEventPumps::instance().obtain(mPostend)
+ .post(LLSDMap
+ ("id", getProcessID())
+ ("desc", mDesc)
+ ("state", mStatus.mState)
+ ("data", mStatus.mData)
+ ("string", getStatusString())
+ );
+ }
+}
+
+LLProcess::id LLProcess::getProcessID() const
+{
+ return mProcess.pid;
+}
+
+LLProcess::handle LLProcess::getProcessHandle() const
+{
+#if LL_WINDOWS
+ return mProcess.hproc;
+#else
+ return mProcess.pid;
+#endif
+}
+
+std::string LLProcess::getPipeName(FILESLOT) const
+{
+ // LLProcess::FileParam::type "npipe" is not yet implemented
+ return "";
+}
+
+template<class PIPETYPE>
+PIPETYPE* LLProcess::getPipePtr(std::string& error, FILESLOT slot)
+{
+ if (slot >= NSLOTS)
+ {
+ error = STRINGIZE(mDesc << " has no slot " << slot);
+ return NULL;
+ }
+ if (mPipes.is_null(slot))
+ {
+ error = STRINGIZE(mDesc << ' ' << whichfile(slot) << " not a monitored pipe");
+ return NULL;
+ }
+ // Make sure we dynamic_cast in pointer domain so we can test, rather than
+ // accepting runtime's exception.
+ PIPETYPE* ppipe = dynamic_cast<PIPETYPE*>(&mPipes[slot]);
+ if (! ppipe)
+ {
+ error = STRINGIZE(mDesc << ' ' << whichfile(slot) << " not a " << typeid(PIPETYPE).name());
+ return NULL;
+ }
+
+ error.clear();
+ return ppipe;
+}
+
+template <class PIPETYPE>
+PIPETYPE& LLProcess::getPipe(FILESLOT slot)
+{
+ std::string error;
+ PIPETYPE* wp = getPipePtr<PIPETYPE>(error, slot);
+ if (! wp)
+ {
+ throw NoPipe(error);
+ }
+ return *wp;
+}
+
+template <class PIPETYPE>
+boost::optional<PIPETYPE&> LLProcess::getOptPipe(FILESLOT slot)
+{
+ std::string error;
+ PIPETYPE* wp = getPipePtr<PIPETYPE>(error, slot);
+ if (! wp)
+ {
+ LL_DEBUGS("LLProcess") << error << LL_ENDL;
+ return boost::optional<PIPETYPE&>();
+ }
+ return *wp;
+}
+
+LLProcess::WritePipe& LLProcess::getWritePipe(FILESLOT slot)
+{
+ return getPipe<WritePipe>(slot);
+}
+
+boost::optional<LLProcess::WritePipe&> LLProcess::getOptWritePipe(FILESLOT slot)
+{
+ return getOptPipe<WritePipe>(slot);
+}
+
+LLProcess::ReadPipe& LLProcess::getReadPipe(FILESLOT slot)
+{
+ return getPipe<ReadPipe>(slot);
+}
+
+boost::optional<LLProcess::ReadPipe&> LLProcess::getOptReadPipe(FILESLOT slot)
+{
+ return getOptPipe<ReadPipe>(slot);
+}
+
+std::ostream& operator<<(std::ostream& out, const LLProcess::Params& params)
+{
+ if (params.cwd.isProvided())
+ {
+ out << "cd " << LLStringUtil::quote(params.cwd) << ": ";
+ }
+ out << LLStringUtil::quote(params.executable);
+ BOOST_FOREACH(const std::string& arg, params.args)
+ {
+ out << ' ' << LLStringUtil::quote(arg);
+ }
+ return out;
+}
+
+/*****************************************************************************
+* Windows specific
+*****************************************************************************/
+#if LL_WINDOWS
+
+static std::string WindowsErrorString(const std::string& operation);
+
+void LLProcess::autokill()
+{
+ // hopefully now handled by apr_procattr_autokill_set()
+}
+
+LLProcess::handle LLProcess::isRunning(handle h, const std::string& desc)
+{
+ // This direct Windows implementation is because we have no access to the
+ // apr_proc_t struct: we expect it's been destroyed.
+ if (! h)
+ return 0;
+
+ DWORD waitresult = WaitForSingleObject(h, 0);
+ if(waitresult == WAIT_OBJECT_0)
+ {
+ // the process has completed.
+ if (! desc.empty())
+ {
+ DWORD status = 0;
+ if (! GetExitCodeProcess(h, &status))
+ {
+ LL_WARNS("LLProcess") << desc << " terminated, but "
+ << WindowsErrorString("GetExitCodeProcess()") << LL_ENDL;
+ }
+ {
+ LL_INFOS("LLProcess") << getStatusString(desc, interpret_status(status))
+ << LL_ENDL;
+ }
+ }
+ CloseHandle(h);
+ return 0;
+ }
+
+ return h;
+}
+
+static LLProcess::Status interpret_status(int status)
+{
+ LLProcess::Status result;
+
+ // This bit of code is cribbed from apr/threadproc/win32/proc.c, a
+ // function (unfortunately static) called why_from_exit_code():
+ /* See WinNT.h STATUS_ACCESS_VIOLATION and family for how
+ * this class of failures was determined
+ */
+ if ((status & 0xFFFF0000) == 0xC0000000)
+ {
+ result.mState = LLProcess::KILLED;
+ }
+ else
+ {
+ result.mState = LLProcess::EXITED;
+ }
+ result.mData = status;
+
+ return result;
+}
+
+/// GetLastError()/FormatMessage() boilerplate
+static std::string WindowsErrorString(const std::string& operation)
+{
+ int result = GetLastError();
+
+ LPTSTR error_str = 0;
+ if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ result,
+ 0,
+ (LPTSTR)&error_str,
+ 0,
+ NULL)
+ != 0)
+ {
+ // convert from wide-char string to multi-byte string
+ char message[256];
+ wcstombs(message, error_str, sizeof(message));
+ message[sizeof(message)-1] = 0;
+ LocalFree(error_str);
+ // convert to std::string to trim trailing whitespace
+ std::string mbsstr(message);
+ mbsstr.erase(mbsstr.find_last_not_of(" \t\r\n"));
+ return STRINGIZE(operation << " failed (" << result << "): " << mbsstr);
+ }
+ return STRINGIZE(operation << " failed (" << result
+ << "), but FormatMessage() did not explain");
+}
+
+/*****************************************************************************
+* Posix specific
+*****************************************************************************/
+#else // Mac and linux
+
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+void LLProcess::autokill()
+{
+ // What we ought to do here is to:
+ // 1. create a unique process group and run all autokill children in that
+ // group (see https://jira.secondlife.com/browse/SWAT-563);
+ // 2. figure out a way to intercept control when the viewer exits --
+ // gracefully or not;
+ // 3. when the viewer exits, kill off the aforementioned process group.
+
+ // It's point 2 that's troublesome. Although I've seen some signal-
+ // handling logic in the Posix viewer code, I haven't yet found any bit of
+ // code that's run no matter how the viewer exits (a try/finally for the
+ // whole process, as it were).
+}
+
+// Attempt to reap a process ID -- returns true if the process has exited and been reaped, false otherwise.
+static bool reap_pid(pid_t pid, LLProcess::Status* pstatus=NULL)
+{
+ LLProcess::Status dummy;
+ if (! pstatus)
+ {
+ // If caller doesn't want to see Status, give us a target anyway so we
+ // don't have to have a bunch of conditionals.
+ pstatus = &dummy;
+ }
+
+ int status = 0;
+ pid_t wait_result = ::waitpid(pid, &status, WNOHANG);
+ if (wait_result == pid)
+ {
+ *pstatus = interpret_status(status);
+ return true;
+ }
+ if (wait_result == 0)
+ {
+ pstatus->mState = LLProcess::RUNNING;
+ pstatus->mData = 0;
+ return false;
+ }
+
+ // Clear caller's Status block; caller must interpret UNSTARTED to mean
+ // "if this PID was ever valid, it no longer is."
+ *pstatus = LLProcess::Status();
+
+ // We've dealt with the success cases: we were able to reap the child
+ // (wait_result == pid) or it's still running (wait_result == 0). It may
+ // be that the child terminated but didn't hang around long enough for us
+ // to reap. In that case we still have no Status to report, but we can at
+ // least state that it's not running.
+ if (wait_result == -1 && errno == ECHILD)
+ {
+ // No such process -- this may mean we're ignoring SIGCHILD.
+ return true;
+ }
+
+ // Uh, should never happen?!
+ LL_WARNS("LLProcess") << "LLProcess::reap_pid(): waitpid(" << pid << ") returned "
+ << wait_result << "; not meaningful?" << LL_ENDL;
+ // If caller is looping until this pid terminates, and if we can't find
+ // out, better to break the loop than to claim it's still running.
+ return true;
+}
+
+LLProcess::id LLProcess::isRunning(id pid, const std::string& desc)
+{
+ // This direct Posix implementation is because we have no access to the
+ // apr_proc_t struct: we expect it's been destroyed.
+ if (! pid)
+ return 0;
+
+ // Check whether the process has exited, and reap it if it has.
+ LLProcess::Status status;
+ if(reap_pid(pid, &status))
+ {
+ // the process has exited.
+ if (! desc.empty())
+ {
+ std::string statstr(desc + " apparently terminated: no status available");
+ // We don't just pass UNSTARTED to getStatusString() because, in
+ // the context of reap_pid(), that state has special meaning.
+ if (status.mState != UNSTARTED)
+ {
+ statstr = getStatusString(desc, status);
+ }
+ LL_INFOS("LLProcess") << statstr << LL_ENDL;
+ }
+ return 0;
+ }
+
+ return pid;
+}
+
+static LLProcess::Status interpret_status(int status)
+{
+ LLProcess::Status result;
+
+ if (WIFEXITED(status))
+ {
+ result.mState = LLProcess::EXITED;
+ result.mData = WEXITSTATUS(status);
+ }
+ else if (WIFSIGNALED(status))
+ {
+ result.mState = LLProcess::KILLED;
+ result.mData = WTERMSIG(status);
+ }
+ else // uh, shouldn't happen?
+ {
+ result.mState = LLProcess::EXITED;
+ result.mData = status; // someone else will have to decode
+ }
+
+ return result;
+}
+
+/*==========================================================================*|
+static std::list<pid_t> sZombies;
+
+void LLProcess::orphan(void)
+{
+ // Disassociate the process from this object
+ if(mProcessID != 0)
+ {
+ // We may still need to reap the process's zombie eventually
+ sZombies.push_back(mProcessID);
+
+ mProcessID = 0;
+ }
+}
+
+// static
+void LLProcess::reap(void)
+{
+ // Attempt to real all saved process ID's.
+
+ std::list<pid_t>::iterator iter = sZombies.begin();
+ while(iter != sZombies.end())
+ {
+ if(reap_pid(*iter))
+ {
+ iter = sZombies.erase(iter);
+ }
+ else
+ {
+ iter++;
+ }
+ }
+}
+|*==========================================================================*/
+#endif // Posix
diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h
new file mode 100644
index 0000000000..637b7e2f9c
--- /dev/null
+++ b/indra/llcommon/llprocess.h
@@ -0,0 +1,519 @@
+/**
+ * @file llprocess.h
+ * @brief Utility class for launching, terminating, and tracking child processes.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPROCESS_H
+#define LL_LLPROCESS_H
+
+#include "llinitparam.h"
+#include "llsdparam.h"
+#include "apr_thread_proc.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/optional.hpp>
+#include <boost/noncopyable.hpp>
+#include <iosfwd> // std::ostream
+#include <stdexcept>
+
+#if LL_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h> // HANDLE (eye roll)
+#elif LL_LINUX
+#if defined(Status)
+#undef Status
+#endif
+#endif
+
+class LLEventPump;
+
+class LLProcess;
+/// LLProcess instances are created on the heap by static factory methods and
+/// managed by ref-counted pointers.
+typedef boost::shared_ptr<LLProcess> LLProcessPtr;
+
+/**
+ * LLProcess handles launching an external process with specified command line
+ * arguments. It also keeps track of whether the process is still running, and
+ * can kill it if required.
+ *
+ * In discussing LLProcess, we use the term "parent" to refer to this process
+ * (the process invoking LLProcess), versus "child" to refer to the process
+ * spawned by LLProcess.
+ *
+ * LLProcess relies on periodic post() calls on the "mainloop" LLEventPump: an
+ * LLProcess object's Status won't update until the next "mainloop" tick. For
+ * instance, the Second Life viewer's main loop already posts to an
+ * LLEventPump by that name once per iteration. See
+ * indra/llcommon/tests/llprocess_test.cpp for an example of waiting for
+ * child-process termination in a standalone test context.
+ */
+class LL_COMMON_API LLProcess: public boost::noncopyable
+{
+ LOG_CLASS(LLProcess);
+public:
+ /**
+ * Specify what to pass for each of child stdin, stdout, stderr.
+ * @see LLProcess::Params::files.
+ */
+ struct FileParam: public LLInitParam::Block<FileParam>
+ {
+ /**
+ * type of file handle to pass to child process
+ *
+ * - "" (default): let the child inherit the same file handle used by
+ * this process. For instance, if passed as stdout, child stdout
+ * will be interleaved with stdout from this process. In this case,
+ * @a name is moot and should be left "".
+ *
+ * - "file": open an OS filesystem file with the specified @a name.
+ * <i>Not yet implemented.</i>
+ *
+ * - "pipe" or "tpipe" or "npipe": depends on @a name
+ *
+ * - @a name.empty(): construct an OS pipe used only for this slot
+ * of the forthcoming child process.
+ *
+ * - ! @a name.empty(): in a global registry, find or create (using
+ * the specified @a name) an OS pipe. The point of the (purely
+ * internal) @a name is that passing the same @a name in more than
+ * one slot for a given LLProcess -- or for slots in different
+ * LLProcess instances -- means the same pipe. For example, you
+ * might pass the same @a name value as both stdout and stderr to
+ * make the child process produce both on the same actual pipe. Or
+ * you might pass the same @a name as the stdout for one LLProcess
+ * and the stdin for another to connect the two child processes.
+ * Use LLProcess::getPipeName() to generate a unique name
+ * guaranteed not to already exist in the registry. <i>Not yet
+ * implemented.</i>
+ *
+ * The difference between "pipe", "tpipe" and "npipe" is as follows.
+ *
+ * - "pipe": direct LLProcess to monitor the parent end of the pipe,
+ * pumping nonblocking I/O every frame. The expectation (at least
+ * for stdout or stderr) is that the caller will listen for
+ * incoming data and consume it as it arrives. It's important not
+ * to neglect such a pipe, because it's buffered in memory. If you
+ * suspect the child may produce a great volume of output between
+ * frames, consider directing the child to write to a filesystem
+ * file instead, then read the file later.
+ *
+ * - "tpipe": do not engage LLProcess machinery to monitor the
+ * parent end of the pipe. A "tpipe" is used only to connect
+ * different child processes. As such, it makes little sense to
+ * pass an empty @a name. <i>Not yet implemented.</i>
+ *
+ * - "npipe": like "tpipe", but use an OS named pipe with a
+ * generated name. Note that @a name is the @em internal name of
+ * the pipe in our global registry -- it doesn't necessarily have
+ * anything to do with the pipe's name in the OS filesystem. Use
+ * LLProcess::getPipeName() to obtain the named pipe's OS
+ * filesystem name, e.g. to pass it as the @a name to another
+ * LLProcess instance using @a type "file". This supports usage
+ * like bash's &lt;(subcommand...) or &gt;(subcommand...)
+ * constructs. <i>Not yet implemented.</i>
+ *
+ * In all cases the open mode (read, write) is determined by the child
+ * slot you're filling. Child stdin means select the "read" end of a
+ * pipe, or open a filesystem file for reading; child stdout or stderr
+ * means select the "write" end of a pipe, or open a filesystem file
+ * for writing.
+ *
+ * Confusion such as passing the same pipe as the stdin of two
+ * processes (rather than stdout for one and stdin for the other) is
+ * explicitly permitted: it's up to the caller to construct meaningful
+ * LLProcess pipe graphs.
+ */
+ Optional<std::string> type;
+ Optional<std::string> name;
+
+ FileParam(const std::string& tp="", const std::string& nm=""):
+ type("type"),
+ name("name")
+ {
+ // If caller wants to specify values, use explicit assignment to
+ // set them rather than initialization.
+ if (! tp.empty()) type = tp;
+ if (! nm.empty()) name = nm;
+ }
+ };
+
+ /// Param block definition
+ struct Params: public LLInitParam::Block<Params>
+ {
+ Params():
+ executable("executable"),
+ args("args"),
+ cwd("cwd"),
+ autokill("autokill", true),
+ files("files"),
+ postend("postend"),
+ desc("desc")
+ {}
+
+ /// pathname of executable
+ Mandatory<std::string> executable;
+ /**
+ * zero or more additional command-line arguments. Arguments are
+ * passed through as exactly as we can manage, whitespace and all.
+ * @note On Windows we manage this by implicitly double-quoting each
+ * argument while assembling the command line.
+ */
+ Multiple<std::string> args;
+ /// current working directory, if need it changed
+ Optional<std::string> cwd;
+ /// implicitly kill process on destruction of LLProcess object
+ /// (default true)
+ Optional<bool> autokill;
+ /**
+ * Up to three FileParam items: for child stdin, stdout, stderr.
+ * Passing two FileParam entries means default treatment for stderr,
+ * and so forth.
+ *
+ * @note LLInitParam::Block permits usage like this:
+ * @code
+ * LLProcess::Params params;
+ * ...
+ * params.files
+ * .add(LLProcess::FileParam()) // stdin
+ * .add(LLProcess::FileParam().type("pipe") // stdout
+ * .add(LLProcess::FileParam().type("file").name("error.log"));
+ * @endcode
+ *
+ * @note While it's theoretically plausible to pass additional open
+ * file handles to a child specifically written to expect them, our
+ * underlying implementation doesn't yet support that.
+ */
+ Multiple<FileParam, AtMost<3> > files;
+ /**
+ * On child-process termination, if this LLProcess object still
+ * exists, post LLSD event to LLEventPump with specified name (default
+ * no event). Event contains at least:
+ *
+ * - "id" as obtained from getProcessID()
+ * - "desc" short string description of child (executable + pid)
+ * - "state" @c state enum value, from Status.mState
+ * - "data" if "state" is EXITED, exit code; if KILLED, on Posix,
+ * signal number
+ * - "string" English text describing "state" and "data" (e.g. "exited
+ * with code 0")
+ */
+ Optional<std::string> postend;
+ /**
+ * Description of child process for logging purposes. It need not be
+ * unique; the logged description string will contain the PID as well.
+ * If this is omitted, a description will be derived from the
+ * executable name.
+ */
+ Optional<std::string> desc;
+ };
+ typedef LLSDParamAdapter<Params> LLSDOrParams;
+
+ /**
+ * Factory accepting either plain LLSD::Map or Params block.
+ * MAY RETURN DEFAULT-CONSTRUCTED LLProcessPtr if params invalid!
+ */
+ static LLProcessPtr create(const LLSDOrParams& params);
+ virtual ~LLProcess();
+
+ /// Is child process still running?
+ bool isRunning() const;
+
+ /**
+ * State of child process
+ */
+ enum state
+ {
+ UNSTARTED, ///< initial value, invisible to consumer
+ RUNNING, ///< child process launched
+ EXITED, ///< child process terminated voluntarily
+ KILLED ///< child process terminated involuntarily
+ };
+
+ /**
+ * Status info
+ */
+ struct Status
+ {
+ Status():
+ mState(UNSTARTED),
+ mData(0)
+ {}
+
+ state mState; ///< @see state
+ /**
+ * - for mState == EXITED: mData is exit() code
+ * - for mState == KILLED: mData is signal number (Posix)
+ * - otherwise: mData is undefined
+ */
+ int mData;
+ };
+
+ /// Status query
+ Status getStatus() const;
+ /// English Status string query, for logging etc.
+ std::string getStatusString() const;
+ /// English Status string query for previously-captured Status
+ std::string getStatusString(const Status& status) const;
+ /// static English Status string query
+ static std::string getStatusString(const std::string& desc, const Status& status);
+
+ // Attempt to kill the process -- returns true if the process is no longer running when it returns.
+ // Note that even if this returns false, the process may exit some time after it's called.
+ bool kill(const std::string& who="");
+
+#if LL_WINDOWS
+ typedef int id; ///< as returned by getProcessID()
+ typedef HANDLE handle; ///< as returned by getProcessHandle()
+#else
+ typedef pid_t id;
+ typedef pid_t handle;
+#endif
+ /**
+ * Get an int-like id value. This is primarily intended for a human reader
+ * to differentiate processes.
+ */
+ id getProcessID() const;
+ /**
+ * Get a "handle" of a kind that you might pass to platform-specific API
+ * functions to engage features not directly supported by LLProcess.
+ */
+ handle getProcessHandle() const;
+
+ /**
+ * Test if a process (@c handle obtained from getProcessHandle()) is still
+ * running. Return same nonzero @c handle value if still running, else
+ * zero, so you can test it like a bool. But if you want to update a
+ * stored variable as a side effect, you can write code like this:
+ * @code
+ * hchild = LLProcess::isRunning(hchild);
+ * @endcode
+ * @note This method is intended as a unit-test hook, not as the first of
+ * a whole set of operations supported on freestanding @c handle values.
+ * New functionality should be added as nonstatic members operating on
+ * the same data as getProcessHandle().
+ *
+ * In particular, if child termination is detected by static isRunning()
+ * rather than by nonstatic isRunning(), the LLProcess object won't be
+ * aware of the child's changed status and may encounter OS errors trying
+ * to obtain it. static isRunning() is only intended for after the
+ * launching LLProcess object has been destroyed.
+ */
+ static handle isRunning(handle, const std::string& desc="");
+
+ /// Provide symbolic access to child's file slots
+ enum FILESLOT { STDIN=0, STDOUT=1, STDERR=2, NSLOTS=3 };
+
+ /**
+ * For a pipe constructed with @a type "npipe", obtain the generated OS
+ * filesystem name for the specified pipe. Otherwise returns the empty
+ * string. @see LLProcess::FileParam::type
+ */
+ std::string getPipeName(FILESLOT) const;
+
+ /// base of ReadPipe, WritePipe
+ class LL_COMMON_API BasePipe
+ {
+ public:
+ virtual ~BasePipe() = 0;
+
+ typedef std::size_t size_type;
+ static const size_type npos;
+ };
+
+ /// As returned by getWritePipe() or getOptWritePipe()
+ class WritePipe: public BasePipe
+ {
+ public:
+ /**
+ * Get ostream& on which to write to child's stdin.
+ *
+ * @usage
+ * @code
+ * myProcess->getWritePipe().get_ostream() << "Hello, child!" << std::endl;
+ * @endcode
+ */
+ virtual std::ostream& get_ostream() = 0;
+ };
+
+ /// As returned by getReadPipe() or getOptReadPipe()
+ class ReadPipe: public BasePipe
+ {
+ public:
+ /**
+ * Get istream& on which to read from child's stdout or stderr.
+ *
+ * @usage
+ * @code
+ * std::string stuff;
+ * myProcess->getReadPipe().get_istream() >> stuff;
+ * @endcode
+ *
+ * You should be sure in advance that the ReadPipe in question can
+ * fill the request. @see getPump()
+ */
+ virtual std::istream& get_istream() = 0;
+
+ /**
+ * Get accumulated buffer length.
+ * Often we need to refrain from actually reading the std::istream
+ * returned by get_istream() until we've accumulated enough data to
+ * make it worthwhile. For instance, if we're expecting a number from
+ * the child, but the child happens to flush "12" before emitting
+ * "3\n", get_istream() >> myint could return 12 rather than 123!
+ */
+ virtual size_type size() const = 0;
+
+ /**
+ * Peek at accumulated buffer data without consuming it. Optional
+ * parameters give you substr() functionality.
+ *
+ * @note You can discard buffer data using get_istream().ignore(n).
+ */
+ virtual std::string peek(size_type offset=0, size_type len=npos) const = 0;
+
+ /**
+ * Detect presence of a substring (or char) in accumulated buffer data
+ * without retrieving it. Optional offset allows you to search from
+ * specified position.
+ */
+ template <typename SEEK>
+ bool contains(SEEK seek, size_type offset=0) const
+ { return find(seek, offset) != npos; }
+
+ /**
+ * Search for a substring in accumulated buffer data without
+ * retrieving it. Returns size_type position at which found, or npos
+ * meaning not found. Optional offset allows you to search from
+ * specified position.
+ */
+ virtual size_type find(const std::string& seek, size_type offset=0) const = 0;
+
+ /**
+ * Search for a char in accumulated buffer data without retrieving it.
+ * Returns size_type position at which found, or npos meaning not
+ * found. Optional offset allows you to search from specified
+ * position.
+ */
+ virtual size_type find(char seek, size_type offset=0) const = 0;
+
+ /**
+ * Get LLEventPump& on which to listen for incoming data. The posted
+ * LLSD::Map event will contain a key "data" whose value is an
+ * LLSD::String containing (part of) the data accumulated in the
+ * buffer.
+ *
+ * If the child sends "abc", and this ReadPipe posts "data"="abc", but
+ * you don't consume it by reading the std::istream returned by
+ * get_istream(), and the child next sends "def", ReadPipe will post
+ * "data"="abcdef".
+ */
+ virtual LLEventPump& getPump() = 0;
+
+ /**
+ * Set maximum length of buffer data that will be posted in the LLSD
+ * announcing arrival of new data from the child. If you call
+ * setLimit(5), and the child sends "abcdef", the LLSD event will
+ * contain "data"="abcde". However, you may still read the entire
+ * "abcdef" from get_istream(): this limit affects only the size of
+ * the data posted with the LLSD event. If you don't call this method,
+ * @em no data will be posted: the default is 0 bytes.
+ */
+ virtual void setLimit(size_type limit) = 0;
+
+ /**
+ * Query the current setLimit() limit.
+ */
+ virtual size_type getLimit() const = 0;
+ };
+
+ /// Exception thrown by getWritePipe(), getReadPipe() if you didn't ask to
+ /// create a pipe at the corresponding FILESLOT.
+ struct NoPipe: public std::runtime_error
+ {
+ NoPipe(const std::string& what): std::runtime_error(what) {}
+ };
+
+ /**
+ * Get a reference to the (only) WritePipe for this LLProcess. @a slot, if
+ * specified, must be STDIN. Throws NoPipe if you did not request a "pipe"
+ * for child stdin. Use this method when you know how you created the
+ * LLProcess in hand.
+ */
+ WritePipe& getWritePipe(FILESLOT slot=STDIN);
+
+ /**
+ * Get a boost::optional<WritePipe&> to the (only) WritePipe for this
+ * LLProcess. @a slot, if specified, must be STDIN. The return value is
+ * empty if you did not request a "pipe" for child stdin. Use this method
+ * for inspecting an LLProcess you did not create.
+ */
+ boost::optional<WritePipe&> getOptWritePipe(FILESLOT slot=STDIN);
+
+ /**
+ * Get a reference to one of the ReadPipes for this LLProcess. @a slot, if
+ * specified, must be STDOUT or STDERR. Throws NoPipe if you did not
+ * request a "pipe" for child stdout or stderr. Use this method when you
+ * know how you created the LLProcess in hand.
+ */
+ ReadPipe& getReadPipe(FILESLOT slot);
+
+ /**
+ * Get a boost::optional<ReadPipe&> to one of the ReadPipes for this
+ * LLProcess. @a slot, if specified, must be STDOUT or STDERR. The return
+ * value is empty if you did not request a "pipe" for child stdout or
+ * stderr. Use this method for inspecting an LLProcess you did not create.
+ */
+ boost::optional<ReadPipe&> getOptReadPipe(FILESLOT slot);
+
+private:
+ /// constructor is private: use create() instead
+ LLProcess(const LLSDOrParams& params);
+ void autokill();
+ // Classic-C-style APR callback
+ static void status_callback(int reason, void* data, int status);
+ // Object-oriented callback
+ void handle_status(int reason, int status);
+ // implementation for get[Opt][Read|Write]Pipe()
+ template <class PIPETYPE>
+ PIPETYPE& getPipe(FILESLOT slot);
+ template <class PIPETYPE>
+ boost::optional<PIPETYPE&> getOptPipe(FILESLOT slot);
+ template <class PIPETYPE>
+ PIPETYPE* getPipePtr(std::string& error, FILESLOT slot);
+
+ std::string mDesc;
+ std::string mPostend;
+ apr_proc_t mProcess;
+ bool mAutokill;
+ Status mStatus;
+ // explicitly want this ptr_vector to be able to store NULLs
+ typedef boost::ptr_vector< boost::nullable<BasePipe> > PipeVector;
+ PipeVector mPipes;
+};
+
+/// for logging
+LL_COMMON_API std::ostream& operator<<(std::ostream&, const LLProcess::Params&);
+
+#endif // LL_LLPROCESS_H
diff --git a/indra/llcommon/llprocesslauncher.cpp b/indra/llcommon/llprocesslauncher.cpp
deleted file mode 100644
index 10950181fd..0000000000
--- a/indra/llcommon/llprocesslauncher.cpp
+++ /dev/null
@@ -1,357 +0,0 @@
-/**
- * @file llprocesslauncher.cpp
- * @brief Utility class for launching, terminating, and tracking the state of processes.
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "llprocesslauncher.h"
-
-#include <iostream>
-#if LL_DARWIN || LL_LINUX
-// not required or present on Win32
-#include <sys/wait.h>
-#endif
-
-LLProcessLauncher::LLProcessLauncher()
-{
-#if LL_WINDOWS
- mProcessHandle = 0;
-#else
- mProcessID = 0;
-#endif
-}
-
-LLProcessLauncher::~LLProcessLauncher()
-{
- kill();
-}
-
-void LLProcessLauncher::setExecutable(const std::string &executable)
-{
- mExecutable = executable;
-}
-
-void LLProcessLauncher::setWorkingDirectory(const std::string &dir)
-{
- mWorkingDir = dir;
-}
-
-const std::string& LLProcessLauncher::getExecutable() const
-{
- return mExecutable;
-}
-
-void LLProcessLauncher::clearArguments()
-{
- mLaunchArguments.clear();
-}
-
-void LLProcessLauncher::addArgument(const std::string &arg)
-{
- mLaunchArguments.push_back(arg);
-}
-
-void LLProcessLauncher::addArgument(const char *arg)
-{
- mLaunchArguments.push_back(std::string(arg));
-}
-
-#if LL_WINDOWS
-
-int LLProcessLauncher::launch(void)
-{
- // If there was already a process associated with this object, kill it.
- kill();
- orphan();
-
- int result = 0;
-
- PROCESS_INFORMATION pinfo;
- STARTUPINFOA sinfo;
- memset(&sinfo, 0, sizeof(sinfo));
-
- std::string args = mExecutable;
- for(int i = 0; i < (int)mLaunchArguments.size(); i++)
- {
- args += " ";
- args += mLaunchArguments[i];
- }
-
- // So retarded. Windows requires that the second parameter to CreateProcessA be a writable (non-const) string...
- char *args2 = new char[args.size() + 1];
- strcpy(args2, args.c_str());
-
- const char * working_directory = 0;
- if(!mWorkingDir.empty()) working_directory = mWorkingDir.c_str();
- if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, working_directory, &sinfo, &pinfo ) )
- {
- result = GetLastError();
-
- LPTSTR error_str = 0;
- if(
- FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- result,
- 0,
- (LPTSTR)&error_str,
- 0,
- NULL)
- != 0)
- {
- char message[256];
- wcstombs(message, error_str, 256);
- message[255] = 0;
- llwarns << "CreateProcessA failed: " << message << llendl;
- LocalFree(error_str);
- }
-
- if(result == 0)
- {
- // Make absolutely certain we return a non-zero value on failure.
- result = -1;
- }
- }
- else
- {
- // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on
- // CloseHandle(pinfo.hProcess); // stops leaks - nothing else
- mProcessHandle = pinfo.hProcess;
- CloseHandle(pinfo.hThread); // stops leaks - nothing else
- }
-
- delete[] args2;
-
- return result;
-}
-
-bool LLProcessLauncher::isRunning(void)
-{
- if(mProcessHandle != 0)
- {
- DWORD waitresult = WaitForSingleObject(mProcessHandle, 0);
- if(waitresult == WAIT_OBJECT_0)
- {
- // the process has completed.
- mProcessHandle = 0;
- }
- }
-
- return (mProcessHandle != 0);
-}
-bool LLProcessLauncher::kill(void)
-{
- bool result = true;
-
- if(mProcessHandle != 0)
- {
- TerminateProcess(mProcessHandle,0);
-
- if(isRunning())
- {
- result = false;
- }
- }
-
- return result;
-}
-
-void LLProcessLauncher::orphan(void)
-{
- // Forget about the process
- mProcessHandle = 0;
-}
-
-// static
-void LLProcessLauncher::reap(void)
-{
- // No actions necessary on Windows.
-}
-
-#else // Mac and linux
-
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-
-static std::list<pid_t> sZombies;
-
-// Attempt to reap a process ID -- returns true if the process has exited and been reaped, false otherwise.
-static bool reap_pid(pid_t pid)
-{
- bool result = false;
-
- pid_t wait_result = ::waitpid(pid, NULL, WNOHANG);
- if(wait_result == pid)
- {
- result = true;
- }
- else if(wait_result == -1)
- {
- if(errno == ECHILD)
- {
- // No such process -- this may mean we're ignoring SIGCHILD.
- result = true;
- }
- }
-
- return result;
-}
-
-int LLProcessLauncher::launch(void)
-{
- // If there was already a process associated with this object, kill it.
- kill();
- orphan();
-
- int result = 0;
- int current_wd = -1;
-
- // create an argv vector for the child process
- const char ** fake_argv = new const char *[mLaunchArguments.size() + 2]; // 1 for the executable path, 1 for the NULL terminator
-
- int i = 0;
-
- // add the executable path
- fake_argv[i++] = mExecutable.c_str();
-
- // and any arguments
- for(int j=0; j < mLaunchArguments.size(); j++)
- fake_argv[i++] = mLaunchArguments[j].c_str();
-
- // terminate with a null pointer
- fake_argv[i] = NULL;
-
- if(!mWorkingDir.empty())
- {
- // save the current working directory
- current_wd = ::open(".", O_RDONLY);
-
- // and change to the one the child will be executed in
- if (::chdir(mWorkingDir.c_str()))
- {
- // chdir failed
- }
- }
-
- // flush all buffers before the child inherits them
- ::fflush(NULL);
-
- pid_t id = vfork();
- if(id == 0)
- {
- // child process
-
- ::execv(mExecutable.c_str(), (char * const *)fake_argv);
-
- // If we reach this point, the exec failed.
- // Use _exit() instead of exit() per the vfork man page.
- _exit(0);
- }
-
- // parent process
-
- if(current_wd >= 0)
- {
- // restore the previous working directory
- if (::fchdir(current_wd))
- {
- // chdir failed
- }
- ::close(current_wd);
- }
-
- delete[] fake_argv;
-
- mProcessID = id;
-
- return result;
-}
-
-bool LLProcessLauncher::isRunning(void)
-{
- if(mProcessID != 0)
- {
- // Check whether the process has exited, and reap it if it has.
- if(reap_pid(mProcessID))
- {
- // the process has exited.
- mProcessID = 0;
- }
- }
-
- return (mProcessID != 0);
-}
-
-bool LLProcessLauncher::kill(void)
-{
- bool result = true;
-
- if(mProcessID != 0)
- {
- // Try to kill the process. We'll do approximately the same thing whether the kill returns an error or not, so we ignore the result.
- (void)::kill(mProcessID, SIGTERM);
-
- // This will have the side-effect of reaping the zombie if the process has exited.
- if(isRunning())
- {
- result = false;
- }
- }
-
- return result;
-}
-
-void LLProcessLauncher::orphan(void)
-{
- // Disassociate the process from this object
- if(mProcessID != 0)
- {
- // We may still need to reap the process's zombie eventually
- sZombies.push_back(mProcessID);
-
- mProcessID = 0;
- }
-}
-
-// static
-void LLProcessLauncher::reap(void)
-{
- // Attempt to real all saved process ID's.
-
- std::list<pid_t>::iterator iter = sZombies.begin();
- while(iter != sZombies.end())
- {
- if(reap_pid(*iter))
- {
- iter = sZombies.erase(iter);
- }
- else
- {
- iter++;
- }
- }
-}
-
-#endif
diff --git a/indra/llcommon/llprocesslauncher.h b/indra/llcommon/llprocesslauncher.h
deleted file mode 100644
index 954c249147..0000000000
--- a/indra/llcommon/llprocesslauncher.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * @file llprocesslauncher.h
- * @brief Utility class for launching, terminating, and tracking the state of processes.
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLPROCESSLAUNCHER_H
-#define LL_LLPROCESSLAUNCHER_H
-
-#if LL_WINDOWS
-#include <windows.h>
-#endif
-
-
-/*
- LLProcessLauncher handles launching external processes with specified command line arguments.
- It also keeps track of whether the process is still running, and can kill it if required.
-*/
-
-class LL_COMMON_API LLProcessLauncher
-{
- LOG_CLASS(LLProcessLauncher);
-public:
- LLProcessLauncher();
- virtual ~LLProcessLauncher();
-
- void setExecutable(const std::string &executable);
- void setWorkingDirectory(const std::string &dir);
-
- const std::string& getExecutable() const;
-
- void clearArguments();
- void addArgument(const std::string &arg);
- void addArgument(const char *arg);
-
- int launch(void);
- bool isRunning(void);
-
- // Attempt to kill the process -- returns true if the process is no longer running when it returns.
- // Note that even if this returns false, the process may exit some time after it's called.
- bool kill(void);
-
- // Use this if you want the external process to continue execution after the LLProcessLauncher instance controlling it is deleted.
- // Normally, the destructor will attempt to kill the process and wait for termination.
- // This should only be used if the viewer is about to exit -- otherwise, the child process will become a zombie after it exits.
- void orphan(void);
-
- // This needs to be called periodically on Mac/Linux to clean up zombie processes.
- static void reap(void);
-
- // Accessors for platform-specific process ID
-#if LL_WINDOWS
- HANDLE getProcessHandle() { return mProcessHandle; };
-#else
- pid_t getProcessID() { return mProcessID; };
-#endif
-
-private:
- std::string mExecutable;
- std::string mWorkingDir;
- std::vector<std::string> mLaunchArguments;
-
-#if LL_WINDOWS
- HANDLE mProcessHandle;
-#else
- pid_t mProcessID;
-#endif
-};
-
-#endif // LL_LLPROCESSLAUNCHER_H
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 5dee7a3541..1738c16dea 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -109,7 +109,7 @@ void LLQueuedThread::shutdown()
// MAIN THREAD
// virtual
-S32 LLQueuedThread::update(U32 max_time_ms)
+S32 LLQueuedThread::update(F32 max_time_ms)
{
if (!mStarted)
{
@@ -122,7 +122,7 @@ S32 LLQueuedThread::update(U32 max_time_ms)
return updateQueue(max_time_ms);
}
-S32 LLQueuedThread::updateQueue(U32 max_time_ms)
+S32 LLQueuedThread::updateQueue(F32 max_time_ms)
{
F64 max_time = (F64)max_time_ms * .001;
LLTimer timer;
diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h
index 499d13a792..d3704b0fe2 100644
--- a/indra/llcommon/llqueuedthread.h
+++ b/indra/llcommon/llqueuedthread.h
@@ -173,8 +173,8 @@ protected:
public:
bool waitForResult(handle_t handle, bool auto_complete = true);
- virtual S32 update(U32 max_time_ms);
- S32 updateQueue(U32 max_time_ms);
+ virtual S32 update(F32 max_time_ms);
+ S32 updateQueue(F32 max_time_ms);
void waitOnPending();
void printQueueStats();
diff --git a/indra/llxuixml/llregistry.h b/indra/llcommon/llregistry.h
index 36ce6a97b7..36ce6a97b7 100644
--- a/indra/llxuixml/llregistry.h
+++ b/indra/llcommon/llregistry.h
diff --git a/indra/llui/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
index 0e29873bb0..0e29873bb0 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llcommon/llsdparam.cpp
diff --git a/indra/llui/llsdparam.h b/indra/llcommon/llsdparam.h
index 3dfc6d020e..6ef5debd7b 100644
--- a/indra/llui/llsdparam.h
+++ b/indra/llcommon/llsdparam.h
@@ -31,7 +31,7 @@
#include "llinitparam.h"
#include "boost/function.hpp"
-struct LLParamSDParserUtilities
+struct LL_COMMON_API LLParamSDParserUtilities
{
static LLSD& getSDWriteNode(LLSD& input, LLInitParam::Parser::name_stack_range_t& name_stack_range);
@@ -40,7 +40,7 @@ struct LLParamSDParserUtilities
static void readSDValues(read_sd_cb_t cb, const LLSD& sd);
};
-class LLParamSDParser
+class LL_COMMON_API LLParamSDParser
: public LLInitParam::Parser
{
LOG_CLASS(LLParamSDParser);
@@ -92,7 +92,7 @@ private:
};
-extern LLFastTimer::DeclareTimer FTM_SD_PARAM_ADAPTOR;
+extern LL_COMMON_API LLFastTimer::DeclareTimer FTM_SD_PARAM_ADAPTOR;
template<typename T>
class LLSDParamAdapter : public T
{
diff --git a/indra/llcommon/llstreamqueue.cpp b/indra/llcommon/llstreamqueue.cpp
new file mode 100644
index 0000000000..1116a2b6a2
--- /dev/null
+++ b/indra/llcommon/llstreamqueue.cpp
@@ -0,0 +1,24 @@
+/**
+ * @file llstreamqueue.cpp
+ * @author Nat Goodspeed
+ * @date 2012-01-05
+ * @brief Implementation for llstreamqueue.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llstreamqueue.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+
+// As of this writing, llstreamqueue.h is entirely template-based, therefore
+// we don't strictly need a corresponding .cpp file. However, our CMake test
+// macro assumes one. Here it is.
+bool llstreamqueue_cpp_ignored = true;
diff --git a/indra/llcommon/llstreamqueue.h b/indra/llcommon/llstreamqueue.h
new file mode 100644
index 0000000000..0726bad175
--- /dev/null
+++ b/indra/llcommon/llstreamqueue.h
@@ -0,0 +1,240 @@
+/**
+ * @file llstreamqueue.h
+ * @author Nat Goodspeed
+ * @date 2012-01-04
+ * @brief Definition of LLStreamQueue
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLSTREAMQUEUE_H)
+#define LL_LLSTREAMQUEUE_H
+
+#include <string>
+#include <list>
+#include <iosfwd> // std::streamsize
+#include <boost/iostreams/categories.hpp>
+
+/**
+ * This class is a growable buffer between a producer and consumer. It serves
+ * as a queue usable with Boost.Iostreams -- hence, a "stream queue."
+ *
+ * This is especially useful for buffering nonblocking I/O. For instance, we
+ * want application logic to be able to serialize LLSD to a std::ostream. We
+ * may write more data than the destination pipe can handle all at once, but
+ * it's imperative NOT to block the application-level serialization call. So
+ * we buffer it instead. Successive frames can try nonblocking writes to the
+ * destination pipe until all buffered data has been sent.
+ *
+ * Similarly, we want application logic be able to deserialize LLSD from a
+ * std::istream. Again, we must not block that deserialize call waiting for
+ * more data to arrive from the input pipe! Instead we build up a buffer over
+ * a number of frames, using successive nonblocking reads, until we have
+ * "enough" data to be able to present it through a std::istream.
+ *
+ * @note The use cases for this class overlap somewhat with those for the
+ * LLIOPipe/LLPumpIO hierarchies, and indeed we considered using those. This
+ * class has two virtues over the older machinery:
+ *
+ * # It's vastly simpler -- way fewer concepts. It's not clear to me whether
+ * there were ever LLIOPipe/etc. use cases that demanded all the fanciness
+ * rolled in, or whether they were simply overdesigned. In any case, no
+ * remaining Lindens will admit to familiarity with those classes -- and
+ * they're sufficiently obtuse that it would take considerable learning
+ * curve to figure out how to use them properly. The bottom line is that
+ * current management is not keen on any more engineers climbing that curve.
+ * # This class is designed around available components such as std::string,
+ * std::list, Boost.Iostreams. There's less proprietary code.
+ */
+template <typename Ch>
+class LLGenericStreamQueue
+{
+public:
+ LLGenericStreamQueue():
+ mSize(0),
+ mClosed(false)
+ {}
+
+ /**
+ * Boost.Iostreams Source Device facade for use with other Boost.Iostreams
+ * functionality. LLGenericStreamQueue doesn't quite fit any of the Boost
+ * 1.48 Iostreams concepts; instead it behaves as both a Sink and a
+ * Source. This is its Source facade.
+ */
+ struct Source
+ {
+ typedef Ch char_type;
+ typedef boost::iostreams::source_tag category;
+
+ /// Bind the underlying LLGenericStreamQueue
+ Source(LLGenericStreamQueue& sq):
+ mStreamQueue(sq)
+ {}
+
+ // Read up to n characters from the underlying data source into the
+ // buffer s, returning the number of characters read; return -1 to
+ // indicate EOF
+ std::streamsize read(Ch* s, std::streamsize n)
+ {
+ return mStreamQueue.read(s, n);
+ }
+
+ LLGenericStreamQueue& mStreamQueue;
+ };
+
+ /**
+ * Boost.Iostreams Sink Device facade for use with other Boost.Iostreams
+ * functionality. LLGenericStreamQueue doesn't quite fit any of the Boost
+ * 1.48 Iostreams concepts; instead it behaves as both a Sink and a
+ * Source. This is its Sink facade.
+ */
+ struct Sink
+ {
+ typedef Ch char_type;
+ typedef boost::iostreams::sink_tag category;
+
+ /// Bind the underlying LLGenericStreamQueue
+ Sink(LLGenericStreamQueue& sq):
+ mStreamQueue(sq)
+ {}
+
+ /// Write up to n characters from the buffer s to the output sequence,
+ /// returning the number of characters written
+ std::streamsize write(const Ch* s, std::streamsize n)
+ {
+ return mStreamQueue.write(s, n);
+ }
+
+ /// Send EOF to consumer
+ void close()
+ {
+ mStreamQueue.close();
+ }
+
+ LLGenericStreamQueue& mStreamQueue;
+ };
+
+ /// Present Boost.Iostreams Source facade
+ Source asSource() { return Source(*this); }
+ /// Present Boost.Iostreams Sink facade
+ Sink asSink() { return Sink(*this); }
+
+ /// append data to buffer
+ std::streamsize write(const Ch* s, std::streamsize n)
+ {
+ // Unclear how often we might be asked to write 0 bytes -- perhaps a
+ // naive caller responding to an unready nonblocking read. But if we
+ // do get such a call, don't add a completely empty BufferList entry.
+ if (n == 0)
+ return n;
+ // We could implement this using a single std::string object, a la
+ // ostringstream. But the trouble with appending to a string is that
+ // you might have to recopy all previous contents to grow its size. If
+ // we want this to scale to large data volumes, better to allocate
+ // individual pieces.
+ mBuffer.push_back(string(s, n));
+ mSize += n;
+ return n;
+ }
+
+ /**
+ * Inform this LLGenericStreamQueue that no further data are forthcoming.
+ * For our purposes, close() is strictly a producer-side operation;
+ * there's little point in closing the consumer side.
+ */
+ void close()
+ {
+ mClosed = true;
+ }
+
+ /// consume data from buffer
+ std::streamsize read(Ch* s, std::streamsize n)
+ {
+ // read() is actually a convenience method for peek() followed by
+ // skip().
+ std::streamsize got(peek(s, n));
+ // We can only skip() as many characters as we can peek(); ignore
+ // skip() return here.
+ skip(n);
+ return got;
+ }
+
+ /// Retrieve data from buffer without consuming. Like read(), return -1 on
+ /// EOF.
+ std::streamsize peek(Ch* s, std::streamsize n) const;
+
+ /// Consume data from buffer without retrieving. Unlike read() and peek(),
+ /// at EOF we simply skip 0 characters.
+ std::streamsize skip(std::streamsize n);
+
+ /// How many characters do we currently have buffered?
+ std::streamsize size() const
+ {
+ return mSize;
+ }
+
+private:
+ typedef std::basic_string<Ch> string;
+ typedef std::list<string> BufferList;
+ BufferList mBuffer;
+ std::streamsize mSize;
+ bool mClosed;
+};
+
+template <typename Ch>
+std::streamsize LLGenericStreamQueue<Ch>::peek(Ch* s, std::streamsize n) const
+{
+ // Here we may have to build up 'n' characters from an arbitrary
+ // number of individual BufferList entries.
+ typename BufferList::const_iterator bli(mBuffer.begin()), blend(mBuffer.end());
+ // Indicate EOF if producer has closed the pipe AND we've exhausted
+ // all previously-buffered data.
+ if (mClosed && bli == blend)
+ {
+ return -1;
+ }
+ // Here either producer hasn't yet closed, or we haven't yet exhausted
+ // remaining data.
+ std::streamsize needed(n), got(0);
+ // Loop until either we run out of BufferList entries or we've
+ // completely satisfied the request.
+ for ( ; bli != blend && needed; ++bli)
+ {
+ std::streamsize chunk(std::min(needed, std::streamsize(bli->length())));
+ std::copy(bli->begin(), bli->begin() + chunk, s);
+ needed -= chunk;
+ s += chunk;
+ got += chunk;
+ }
+ return got;
+}
+
+template <typename Ch>
+std::streamsize LLGenericStreamQueue<Ch>::skip(std::streamsize n)
+{
+ typename BufferList::iterator bli(mBuffer.begin()), blend(mBuffer.end());
+ std::streamsize toskip(n), skipped(0);
+ while (bli != blend && toskip >= bli->length())
+ {
+ std::streamsize chunk(bli->length());
+ typename BufferList::iterator zap(bli++);
+ mBuffer.erase(zap);
+ mSize -= chunk;
+ toskip -= chunk;
+ skipped += chunk;
+ }
+ if (bli != blend && toskip)
+ {
+ bli->erase(bli->begin(), bli->begin() + toskip);
+ mSize -= toskip;
+ skipped += toskip;
+ }
+ return skipped;
+}
+
+typedef LLGenericStreamQueue<char> LLStreamQueue;
+typedef LLGenericStreamQueue<wchar_t> LLWStreamQueue;
+
+#endif /* ! defined(LL_LLSTREAMQUEUE_H) */
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index e7fe656808..fa0eb9f72c 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -912,22 +912,24 @@ S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions);
template<>
void LLStringUtil::getTokens(const std::string& instr, std::vector<std::string >& tokens, const std::string& delims)
{
- std::string currToken;
- std::string::size_type begIdx, endIdx;
-
- begIdx = instr.find_first_not_of (delims);
- while (begIdx != std::string::npos)
+ // Starting at offset 0, scan forward for the next non-delimiter. We're
+ // done when the only characters left in 'instr' are delimiters.
+ for (std::string::size_type begIdx, endIdx = 0;
+ (begIdx = instr.find_first_not_of (delims, endIdx)) != std::string::npos; )
{
+ // Found a non-delimiter. After that, find the next delimiter.
endIdx = instr.find_first_of (delims, begIdx);
if (endIdx == std::string::npos)
{
+ // No more delimiters: this token extends to the end of the string.
endIdx = instr.length();
}
- currToken = instr.substr(begIdx, endIdx - begIdx);
+ // extract the token between begIdx and endIdx; substr() needs length
+ std::string currToken(instr.substr(begIdx, endIdx - begIdx));
LLStringUtil::trim (currToken);
tokens.push_back(currToken);
- begIdx = instr.find_first_not_of (delims, endIdx);
+ // next scan past delimiters starts at endIdx
}
}
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 7e41e787b5..5085d32f7f 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -40,6 +40,7 @@
#endif
#include <string.h>
+#include <boost/scoped_ptr.hpp>
#if LL_SOLARIS
// stricmp and strnicmp do not exist on Solaris:
@@ -237,40 +238,77 @@ private:
static std::string sLocale;
public:
- typedef typename std::basic_string<T>::size_type size_type;
+ typedef std::basic_string<T> string_type;
+ typedef typename string_type::size_type size_type;
public:
/////////////////////////////////////////////////////////////////////////////////////////
// Static Utility functions that operate on std::strings
- static const std::basic_string<T> null;
+ static const string_type null;
typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t;
- LL_COMMON_API static void getTokens(const std::basic_string<T>& instr, std::vector<std::basic_string<T> >& tokens, const std::basic_string<T>& delims);
- LL_COMMON_API static void formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals);
- LL_COMMON_API static bool formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, std::basic_string<T> param, S32 secFromEpoch);
- LL_COMMON_API static S32 format(std::basic_string<T>& s, const format_map_t& substitutions);
- LL_COMMON_API static S32 format(std::basic_string<T>& s, const LLSD& substitutions);
- LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const format_map_t& substitutions);
- LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const LLSD& substitutions);
+ /// considers any sequence of delims as a single field separator
+ LL_COMMON_API static void getTokens(const string_type& instr,
+ std::vector<string_type >& tokens,
+ const string_type& delims);
+ /// like simple scan overload, but returns scanned vector
+ static std::vector<string_type> getTokens(const string_type& instr,
+ const string_type& delims);
+ /// add support for keep_delims and quotes (either could be empty string)
+ static void getTokens(const string_type& instr,
+ std::vector<string_type>& tokens,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes=string_type());
+ /// like keep_delims-and-quotes overload, but returns scanned vector
+ static std::vector<string_type> getTokens(const string_type& instr,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes=string_type());
+ /// add support for escapes (could be empty string)
+ static void getTokens(const string_type& instr,
+ std::vector<string_type>& tokens,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes,
+ const string_type& escapes);
+ /// like escapes overload, but returns scanned vector
+ static std::vector<string_type> getTokens(const string_type& instr,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes,
+ const string_type& escapes);
+
+ LL_COMMON_API static void formatNumber(string_type& numStr, string_type decimals);
+ LL_COMMON_API static bool formatDatetime(string_type& replacement, string_type token, string_type param, S32 secFromEpoch);
+ LL_COMMON_API static S32 format(string_type& s, const format_map_t& substitutions);
+ LL_COMMON_API static S32 format(string_type& s, const LLSD& substitutions);
+ LL_COMMON_API static bool simpleReplacement(string_type& replacement, string_type token, const format_map_t& substitutions);
+ LL_COMMON_API static bool simpleReplacement(string_type& replacement, string_type token, const LLSD& substitutions);
LL_COMMON_API static void setLocale (std::string inLocale);
LL_COMMON_API static std::string getLocale (void);
- static bool isValidIndex(const std::basic_string<T>& string, size_type i)
+ static bool isValidIndex(const string_type& string, size_type i)
{
return !string.empty() && (0 <= i) && (i <= string.size());
}
- static void trimHead(std::basic_string<T>& string);
- static void trimTail(std::basic_string<T>& string);
- static void trim(std::basic_string<T>& string) { trimHead(string); trimTail(string); }
- static void truncate(std::basic_string<T>& string, size_type count);
+ static bool contains(const string_type& string, T c, size_type i=0)
+ {
+ return string.find(c, i) != string_type::npos;
+ }
- static void toUpper(std::basic_string<T>& string);
- static void toLower(std::basic_string<T>& string);
+ static void trimHead(string_type& string);
+ static void trimTail(string_type& string);
+ static void trim(string_type& string) { trimHead(string); trimTail(string); }
+ static void truncate(string_type& string, size_type count);
+
+ static void toUpper(string_type& string);
+ static void toLower(string_type& string);
// True if this is the head of s.
- static BOOL isHead( const std::basic_string<T>& string, const T* s );
+ static BOOL isHead( const string_type& string, const T* s );
/**
* @brief Returns true if string starts with substr
@@ -278,8 +316,8 @@ public:
* If etither string or substr are empty, this method returns false.
*/
static bool startsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr);
+ const string_type& string,
+ const string_type& substr);
/**
* @brief Returns true if string ends in substr
@@ -287,19 +325,32 @@ public:
* If etither string or substr are empty, this method returns false.
*/
static bool endsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr);
+ const string_type& string,
+ const string_type& substr);
- static void addCRLF(std::basic_string<T>& string);
- static void removeCRLF(std::basic_string<T>& string);
+ static void addCRLF(string_type& string);
+ static void removeCRLF(string_type& string);
- static void replaceTabsWithSpaces( std::basic_string<T>& string, size_type spaces_per_tab );
- static void replaceNonstandardASCII( std::basic_string<T>& string, T replacement );
- static void replaceChar( std::basic_string<T>& string, T target, T replacement );
- static void replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement );
+ static void replaceTabsWithSpaces( string_type& string, size_type spaces_per_tab );
+ static void replaceNonstandardASCII( string_type& string, T replacement );
+ static void replaceChar( string_type& string, T target, T replacement );
+ static void replaceString( string_type& string, string_type target, string_type replacement );
- static BOOL containsNonprintable(const std::basic_string<T>& string);
- static void stripNonprintable(std::basic_string<T>& string);
+ static BOOL containsNonprintable(const string_type& string);
+ static void stripNonprintable(string_type& string);
+
+ /**
+ * Double-quote an argument string if needed, unless it's already
+ * double-quoted. Decide whether it's needed based on the presence of any
+ * character in @a triggers (default space or double-quote). If we quote
+ * it, escape any embedded double-quote with the @a escape string (default
+ * backslash).
+ *
+ * Passing triggers="" means always quote, unless it's already double-quoted.
+ */
+ static string_type quote(const string_type& str,
+ const string_type& triggers=" \"",
+ const string_type& escape="\\");
/**
* @brief Unsafe way to make ascii characters. You should probably
@@ -308,18 +359,18 @@ public:
* The 2 and 4 byte std::string probably work, so LLWStringUtil::_makeASCII
* should work.
*/
- static void _makeASCII(std::basic_string<T>& string);
+ static void _makeASCII(string_type& string);
// Conversion to other data types
- static BOOL convertToBOOL(const std::basic_string<T>& string, BOOL& value);
- static BOOL convertToU8(const std::basic_string<T>& string, U8& value);
- static BOOL convertToS8(const std::basic_string<T>& string, S8& value);
- static BOOL convertToS16(const std::basic_string<T>& string, S16& value);
- static BOOL convertToU16(const std::basic_string<T>& string, U16& value);
- static BOOL convertToU32(const std::basic_string<T>& string, U32& value);
- static BOOL convertToS32(const std::basic_string<T>& string, S32& value);
- static BOOL convertToF32(const std::basic_string<T>& string, F32& value);
- static BOOL convertToF64(const std::basic_string<T>& string, F64& value);
+ static BOOL convertToBOOL(const string_type& string, BOOL& value);
+ static BOOL convertToU8(const string_type& string, U8& value);
+ static BOOL convertToS8(const string_type& string, S8& value);
+ static BOOL convertToS16(const string_type& string, S16& value);
+ static BOOL convertToU16(const string_type& string, U16& value);
+ static BOOL convertToU32(const string_type& string, U32& value);
+ static BOOL convertToS32(const string_type& string, S32& value);
+ static BOOL convertToF32(const string_type& string, F32& value);
+ static BOOL convertToF64(const string_type& string, F64& value);
/////////////////////////////////////////////////////////////////////////////////////////
// Utility functions for working with char*'s and strings
@@ -327,24 +378,24 @@ public:
// Like strcmp but also handles empty strings. Uses
// current locale.
static S32 compareStrings(const T* lhs, const T* rhs);
- static S32 compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
+ static S32 compareStrings(const string_type& lhs, const string_type& rhs);
// case insensitive version of above. Uses current locale on
// Win32, and falls back to a non-locale aware comparison on
// Linux.
static S32 compareInsensitive(const T* lhs, const T* rhs);
- static S32 compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
+ static S32 compareInsensitive(const string_type& lhs, const string_type& rhs);
// Case sensitive comparison with good handling of numbers. Does not use current locale.
// a.k.a. strdictcmp()
- static S32 compareDict(const std::basic_string<T>& a, const std::basic_string<T>& b);
+ static S32 compareDict(const string_type& a, const string_type& b);
// Case *in*sensitive comparison with good handling of numbers. Does not use current locale.
// a.k.a. strdictcmp()
- static S32 compareDictInsensitive(const std::basic_string<T>& a, const std::basic_string<T>& b);
+ static S32 compareDictInsensitive(const string_type& a, const string_type& b);
// Puts compareDict() in a form appropriate for LL container classes to use for sorting.
- static BOOL precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b );
+ static BOOL precedesDict( const string_type& a, const string_type& b );
// A replacement for strncpy.
// If the dst buffer is dst_size bytes long or more, ensures that dst is null terminated and holds
@@ -352,7 +403,7 @@ public:
static void copy(T* dst, const T* src, size_type dst_size);
// Copies src into dst at a given offset.
- static void copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset);
+ static void copyInto(string_type& dst, const string_type& src, size_type offset);
static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); }
@@ -362,7 +413,7 @@ public:
#endif
private:
- LL_COMMON_API static size_type getSubstitution(const std::basic_string<T>& instr, size_type& start, std::vector<std::basic_string<T> >& tokens);
+ LL_COMMON_API static size_type getSubstitution(const string_type& instr, size_type& start, std::vector<string_type >& tokens);
};
template<class T> const std::basic_string<T> LLStringUtilBase<T>::null;
@@ -636,10 +687,325 @@ namespace LLStringFn
////////////////////////////////////////////////////////////
// NOTE: LLStringUtil::format, getTokens, and support functions moved to llstring.cpp.
// There is no LLWStringUtil::format implementation currently.
-// Calling thse for anything other than LLStringUtil will produce link errors.
+// Calling these for anything other than LLStringUtil will produce link errors.
////////////////////////////////////////////////////////////
+// static
+template <class T>
+std::vector<typename LLStringUtilBase<T>::string_type>
+LLStringUtilBase<T>::getTokens(const string_type& instr, const string_type& delims)
+{
+ std::vector<string_type> tokens;
+ getTokens(instr, tokens, delims);
+ return tokens;
+}
+
+// static
+template <class T>
+std::vector<typename LLStringUtilBase<T>::string_type>
+LLStringUtilBase<T>::getTokens(const string_type& instr,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes)
+{
+ std::vector<string_type> tokens;
+ getTokens(instr, tokens, drop_delims, keep_delims, quotes);
+ return tokens;
+}
+
+// static
+template <class T>
+std::vector<typename LLStringUtilBase<T>::string_type>
+LLStringUtilBase<T>::getTokens(const string_type& instr,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes,
+ const string_type& escapes)
+{
+ std::vector<string_type> tokens;
+ getTokens(instr, tokens, drop_delims, keep_delims, quotes, escapes);
+ return tokens;
+}
+
+namespace LLStringUtilBaseImpl
+{
+
+/**
+ * Input string scanner helper for getTokens(), or really any other
+ * character-parsing routine that may have to deal with escape characters.
+ * This implementation defines the concept (also an interface, should you
+ * choose to implement the concept by subclassing) and provides trivial
+ * implementations for a string @em without escape processing.
+ */
+template <class T>
+struct InString
+{
+ typedef std::basic_string<T> string_type;
+ typedef typename string_type::const_iterator const_iterator;
+
+ InString(const_iterator b, const_iterator e):
+ iter(b),
+ end(e)
+ {}
+ virtual ~InString() {}
+
+ bool done() const { return iter == end; }
+ /// Is the current character (*iter) escaped? This implementation can
+ /// answer trivially because it doesn't support escapes.
+ virtual bool escaped() const { return false; }
+ /// Obtain the current character and advance @c iter.
+ virtual T next() { return *iter++; }
+ /// Does the current character match specified character?
+ virtual bool is(T ch) const { return (! done()) && *iter == ch; }
+ /// Is the current character any one of the specified characters?
+ virtual bool oneof(const string_type& delims) const
+ {
+ return (! done()) && LLStringUtilBase<T>::contains(delims, *iter);
+ }
+
+ /**
+ * Scan forward from @from until either @a delim or end. This is primarily
+ * useful for processing quoted substrings.
+ *
+ * If we do see @a delim, append everything from @from until (excluding)
+ * @a delim to @a into, advance @c iter to skip @a delim, and return @c
+ * true.
+ *
+ * If we do not see @a delim, do not alter @a into or @c iter and return
+ * @c false. Do not pass GO, do not collect $200.
+ *
+ * @note The @c false case described above implements normal getTokens()
+ * treatment of an unmatched open quote: treat the quote character as if
+ * escaped, that is, simply collect it as part of the current token. Other
+ * plausible behaviors directly affect the way getTokens() deals with an
+ * unmatched quote: e.g. throwing an exception to treat it as an error, or
+ * assuming a close quote beyond end of string (in which case return @c
+ * true).
+ */
+ virtual bool collect_until(string_type& into, const_iterator from, T delim)
+ {
+ const_iterator found = std::find(from, end, delim);
+ // If we didn't find delim, change nothing, just tell caller.
+ if (found == end)
+ return false;
+ // Found delim! Append everything between from and found.
+ into.append(from, found);
+ // advance past delim in input
+ iter = found + 1;
+ return true;
+ }
+
+ const_iterator iter, end;
+};
+
+/// InString subclass that handles escape characters
+template <class T>
+class InEscString: public InString<T>
+{
+public:
+ typedef InString<T> super;
+ typedef typename super::string_type string_type;
+ typedef typename super::const_iterator const_iterator;
+ using super::done;
+ using super::iter;
+ using super::end;
+
+ InEscString(const_iterator b, const_iterator e, const string_type& escapes_):
+ super(b, e),
+ escapes(escapes_)
+ {
+ // Even though we've already initialized 'iter' via our base-class
+ // constructor, set it again to check for initial escape char.
+ setiter(b);
+ }
+
+ /// This implementation uses the answer cached by setiter().
+ virtual bool escaped() const { return isesc; }
+ virtual T next()
+ {
+ // If we're looking at the escape character of an escape sequence,
+ // skip that character. This is the one time we can modify 'iter'
+ // without using setiter: for this one case we DO NOT CARE if the
+ // escaped character is itself an escape.
+ if (isesc)
+ ++iter;
+ // If we were looking at an escape character, this is the escaped
+ // character; otherwise it's just the next character.
+ T result(*iter);
+ // Advance iter, checking for escape sequence.
+ setiter(iter + 1);
+ return result;
+ }
+
+ virtual bool is(T ch) const
+ {
+ // Like base-class is(), except that an escaped character matches
+ // nothing.
+ return (! done()) && (! isesc) && *iter == ch;
+ }
+
+ virtual bool oneof(const string_type& delims) const
+ {
+ // Like base-class oneof(), except that an escaped character matches
+ // nothing.
+ return (! done()) && (! isesc) && LLStringUtilBase<T>::contains(delims, *iter);
+ }
+
+ virtual bool collect_until(string_type& into, const_iterator from, T delim)
+ {
+ // Deal with escapes in the characters we collect; that is, an escaped
+ // character must become just that character without the preceding
+ // escape. Collect characters in a separate string rather than
+ // directly appending to 'into' in case we do not find delim, in which
+ // case we're supposed to leave 'into' unmodified.
+ string_type collected;
+ // For scanning purposes, we're going to work directly with 'iter'.
+ // Save its current value in case we fail to see delim.
+ const_iterator save_iter(iter);
+ // Okay, set 'iter', checking for escape.
+ setiter(from);
+ while (! done())
+ {
+ // If we see an unescaped delim, stop and report success.
+ if ((! isesc) && *iter == delim)
+ {
+ // Append collected chars to 'into'.
+ into.append(collected);
+ // Don't forget to advance 'iter' past delim.
+ setiter(iter + 1);
+ return true;
+ }
+ // We're not at end, and either we're not looking at delim or it's
+ // escaped. Collect this character and keep going.
+ collected.push_back(next());
+ }
+ // Here we hit 'end' without ever seeing delim. Restore iter and tell
+ // caller.
+ setiter(save_iter);
+ return false;
+ }
+
+private:
+ void setiter(const_iterator i)
+ {
+ iter = i;
+
+ // Every time we change 'iter', set 'isesc' to be able to repetitively
+ // answer escaped() without having to rescan 'escapes'. isesc caches
+ // contains(escapes, *iter).
+
+ // We're looking at an escaped char if we're not already at end (that
+ // is, *iter is even meaningful); if *iter is in fact one of the
+ // specified escape characters; and if there's one more character
+ // following it. That is, if an escape character is the very last
+ // character of the input string, it loses its special meaning.
+ isesc = (! done()) &&
+ LLStringUtilBase<T>::contains(escapes, *iter) &&
+ (iter+1) != end;
+ }
+
+ const string_type escapes;
+ bool isesc;
+};
+
+/// getTokens() implementation based on InString concept
+template <typename INSTRING, typename string_type>
+void getTokens(INSTRING& instr, std::vector<string_type>& tokens,
+ const string_type& drop_delims, const string_type& keep_delims,
+ const string_type& quotes)
+{
+ // There are times when we want to match either drop_delims or
+ // keep_delims. Concatenate them up front to speed things up.
+ string_type all_delims(drop_delims + keep_delims);
+ // no tokens yet
+ tokens.clear();
+
+ // try for another token
+ while (! instr.done())
+ {
+ // scan past any drop_delims
+ while (instr.oneof(drop_delims))
+ {
+ // skip this drop_delim
+ instr.next();
+ // but if that was the end of the string, done
+ if (instr.done())
+ return;
+ }
+ // found the start of another token: make a slot for it
+ tokens.push_back(string_type());
+ if (instr.oneof(keep_delims))
+ {
+ // *iter is a keep_delim, a token of exactly 1 character. Append
+ // that character to the new token and proceed.
+ tokens.back().push_back(instr.next());
+ continue;
+ }
+ // Here we have a non-delimiter token, which might consist of a mix of
+ // quoted and unquoted parts. Use bash rules for quoting: you can
+ // embed a quoted substring in the midst of an unquoted token (e.g.
+ // ~/"sub dir"/myfile.txt); you can ram two quoted substrings together
+ // to make a single token (e.g. 'He said, "'"Don't."'"'). We diverge
+ // from bash in that bash considers an unmatched quote an error. Our
+ // param signature doesn't allow for errors, so just pretend it's not
+ // a quote and embed it.
+ // At this level, keep scanning until we hit the next delimiter of
+ // either type (drop_delims or keep_delims).
+ while (! instr.oneof(all_delims))
+ {
+ // If we're looking at an open quote, search forward for
+ // a close quote, collecting characters along the way.
+ if (instr.oneof(quotes) &&
+ instr.collect_until(tokens.back(), instr.iter+1, *instr.iter))
+ {
+ // collect_until is cleverly designed to do exactly what we
+ // need here. No further action needed if it returns true.
+ }
+ else
+ {
+ // Either *iter isn't a quote, or there's no matching close
+ // quote: in other words, just an ordinary char. Append it to
+ // current token.
+ tokens.back().push_back(instr.next());
+ }
+ // having scanned that segment of this token, if we've reached the
+ // end of the string, we're done
+ if (instr.done())
+ return;
+ }
+ }
+}
+
+} // namespace LLStringUtilBaseImpl
+
+// static
+template <class T>
+void LLStringUtilBase<T>::getTokens(const string_type& string, std::vector<string_type>& tokens,
+ const string_type& drop_delims, const string_type& keep_delims,
+ const string_type& quotes)
+{
+ // Because this overload doesn't support escapes, use simple InString to
+ // manage input range.
+ LLStringUtilBaseImpl::InString<T> instring(string.begin(), string.end());
+ LLStringUtilBaseImpl::getTokens(instring, tokens, drop_delims, keep_delims, quotes);
+}
+
+// static
+template <class T>
+void LLStringUtilBase<T>::getTokens(const string_type& string, std::vector<string_type>& tokens,
+ const string_type& drop_delims, const string_type& keep_delims,
+ const string_type& quotes, const string_type& escapes)
+{
+ // This overload must deal with escapes. Delegate that to InEscString
+ // (unless there ARE no escapes).
+ boost::scoped_ptr< LLStringUtilBaseImpl::InString<T> > instrp;
+ if (escapes.empty())
+ instrp.reset(new LLStringUtilBaseImpl::InString<T>(string.begin(), string.end()));
+ else
+ instrp.reset(new LLStringUtilBaseImpl::InEscString<T>(string.begin(), string.end(), escapes));
+ LLStringUtilBaseImpl::getTokens(*instrp, tokens, drop_delims, keep_delims, quotes);
+}
// static
template<class T>
@@ -669,7 +1035,7 @@ S32 LLStringUtilBase<T>::compareStrings(const T* lhs, const T* rhs)
//static
template<class T>
-S32 LLStringUtilBase<T>::compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
+S32 LLStringUtilBase<T>::compareStrings(const string_type& lhs, const string_type& rhs)
{
return LLStringOps::collate(lhs.c_str(), rhs.c_str());
}
@@ -695,8 +1061,8 @@ S32 LLStringUtilBase<T>::compareInsensitive(const T* lhs, const T* rhs )
}
else
{
- std::basic_string<T> lhs_string(lhs);
- std::basic_string<T> rhs_string(rhs);
+ string_type lhs_string(lhs);
+ string_type rhs_string(rhs);
LLStringUtilBase<T>::toUpper(lhs_string);
LLStringUtilBase<T>::toUpper(rhs_string);
result = LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
@@ -706,10 +1072,10 @@ S32 LLStringUtilBase<T>::compareInsensitive(const T* lhs, const T* rhs )
//static
template<class T>
-S32 LLStringUtilBase<T>::compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
+S32 LLStringUtilBase<T>::compareInsensitive(const string_type& lhs, const string_type& rhs)
{
- std::basic_string<T> lhs_string(lhs);
- std::basic_string<T> rhs_string(rhs);
+ string_type lhs_string(lhs);
+ string_type rhs_string(rhs);
LLStringUtilBase<T>::toUpper(lhs_string);
LLStringUtilBase<T>::toUpper(rhs_string);
return LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
@@ -720,7 +1086,7 @@ S32 LLStringUtilBase<T>::compareInsensitive(const std::basic_string<T>& lhs, con
//static
template<class T>
-S32 LLStringUtilBase<T>::compareDict(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
+S32 LLStringUtilBase<T>::compareDict(const string_type& astr, const string_type& bstr)
{
const T* a = astr.c_str();
const T* b = bstr.c_str();
@@ -761,7 +1127,7 @@ S32 LLStringUtilBase<T>::compareDict(const std::basic_string<T>& astr, const std
// static
template<class T>
-S32 LLStringUtilBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
+S32 LLStringUtilBase<T>::compareDictInsensitive(const string_type& astr, const string_type& bstr)
{
const T* a = astr.c_str();
const T* b = bstr.c_str();
@@ -796,7 +1162,7 @@ S32 LLStringUtilBase<T>::compareDictInsensitive(const std::basic_string<T>& astr
// Puts compareDict() in a form appropriate for LL container classes to use for sorting.
// static
template<class T>
-BOOL LLStringUtilBase<T>::precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b )
+BOOL LLStringUtilBase<T>::precedesDict( const string_type& a, const string_type& b )
{
if( a.size() && b.size() )
{
@@ -810,7 +1176,7 @@ BOOL LLStringUtilBase<T>::precedesDict( const std::basic_string<T>& a, const std
//static
template<class T>
-void LLStringUtilBase<T>::toUpper(std::basic_string<T>& string)
+void LLStringUtilBase<T>::toUpper(string_type& string)
{
if( !string.empty() )
{
@@ -824,7 +1190,7 @@ void LLStringUtilBase<T>::toUpper(std::basic_string<T>& string)
//static
template<class T>
-void LLStringUtilBase<T>::toLower(std::basic_string<T>& string)
+void LLStringUtilBase<T>::toLower(string_type& string)
{
if( !string.empty() )
{
@@ -838,7 +1204,7 @@ void LLStringUtilBase<T>::toLower(std::basic_string<T>& string)
//static
template<class T>
-void LLStringUtilBase<T>::trimHead(std::basic_string<T>& string)
+void LLStringUtilBase<T>::trimHead(string_type& string)
{
if( !string.empty() )
{
@@ -853,7 +1219,7 @@ void LLStringUtilBase<T>::trimHead(std::basic_string<T>& string)
//static
template<class T>
-void LLStringUtilBase<T>::trimTail(std::basic_string<T>& string)
+void LLStringUtilBase<T>::trimTail(string_type& string)
{
if( string.size() )
{
@@ -872,7 +1238,7 @@ void LLStringUtilBase<T>::trimTail(std::basic_string<T>& string)
// Replace line feeds with carriage return-line feed pairs.
//static
template<class T>
-void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string)
+void LLStringUtilBase<T>::addCRLF(string_type& string)
{
const T LF = 10;
const T CR = 13;
@@ -914,7 +1280,7 @@ void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string)
// Remove all carriage returns
//static
template<class T>
-void LLStringUtilBase<T>::removeCRLF(std::basic_string<T>& string)
+void LLStringUtilBase<T>::removeCRLF(string_type& string)
{
const T CR = 13;
@@ -935,10 +1301,10 @@ void LLStringUtilBase<T>::removeCRLF(std::basic_string<T>& string)
//static
template<class T>
-void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement )
+void LLStringUtilBase<T>::replaceChar( string_type& string, T target, T replacement )
{
size_type found_pos = 0;
- while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
+ while( (found_pos = string.find(target, found_pos)) != string_type::npos )
{
string[found_pos] = replacement;
found_pos++; // avoid infinite defeat if target == replacement
@@ -947,10 +1313,10 @@ void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T
//static
template<class T>
-void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement )
+void LLStringUtilBase<T>::replaceString( string_type& string, string_type target, string_type replacement )
{
size_type found_pos = 0;
- while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
+ while( (found_pos = string.find(target, found_pos)) != string_type::npos )
{
string.replace( found_pos, target.length(), replacement );
found_pos += replacement.length(); // avoid infinite defeat if replacement contains target
@@ -959,7 +1325,7 @@ void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basi
//static
template<class T>
-void LLStringUtilBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T replacement )
+void LLStringUtilBase<T>::replaceNonstandardASCII( string_type& string, T replacement )
{
const char LF = 10;
const S8 MIN = 32;
@@ -979,12 +1345,12 @@ void LLStringUtilBase<T>::replaceNonstandardASCII( std::basic_string<T>& string,
//static
template<class T>
-void LLStringUtilBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_type spaces_per_tab )
+void LLStringUtilBase<T>::replaceTabsWithSpaces( string_type& str, size_type spaces_per_tab )
{
const T TAB = '\t';
const T SPACE = ' ';
- std::basic_string<T> out_str;
+ string_type out_str;
// Replace tabs with spaces
for (size_type i = 0; i < str.length(); i++)
{
@@ -1003,7 +1369,7 @@ void LLStringUtilBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size
//static
template<class T>
-BOOL LLStringUtilBase<T>::containsNonprintable(const std::basic_string<T>& string)
+BOOL LLStringUtilBase<T>::containsNonprintable(const string_type& string)
{
const char MIN = 32;
BOOL rv = FALSE;
@@ -1020,7 +1386,7 @@ BOOL LLStringUtilBase<T>::containsNonprintable(const std::basic_string<T>& strin
//static
template<class T>
-void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
+void LLStringUtilBase<T>::stripNonprintable(string_type& string)
{
const char MIN = 32;
size_type j = 0;
@@ -1051,8 +1417,43 @@ void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
delete []c_string;
}
+template<class T>
+std::basic_string<T> LLStringUtilBase<T>::quote(const string_type& str,
+ const string_type& triggers,
+ const string_type& escape)
+{
+ size_type len(str.length());
+ // If the string is already quoted, assume user knows what s/he's doing.
+ if (len >= 2 && str[0] == '"' && str[len-1] == '"')
+ {
+ return str;
+ }
+
+ // Not already quoted: do we need to? triggers.empty() is a special case
+ // meaning "always quote."
+ if ((! triggers.empty()) && str.find_first_of(triggers) == string_type::npos)
+ {
+ // no trigger characters, don't bother quoting
+ return str;
+ }
+
+ // For whatever reason, we must quote this string.
+ string_type result;
+ result.push_back('"');
+ for (typename string_type::const_iterator ci(str.begin()), cend(str.end()); ci != cend; ++ci)
+ {
+ if (*ci == '"')
+ {
+ result.append(escape);
+ }
+ result.push_back(*ci);
+ }
+ result.push_back('"');
+ return result;
+}
+
template<class T>
-void LLStringUtilBase<T>::_makeASCII(std::basic_string<T>& string)
+void LLStringUtilBase<T>::_makeASCII(string_type& string)
{
// Replace non-ASCII chars with LL_UNKNOWN_CHAR
for (size_type i = 0; i < string.length(); i++)
@@ -1082,7 +1483,7 @@ void LLStringUtilBase<T>::copy( T* dst, const T* src, size_type dst_size )
// static
template<class T>
-void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset)
+void LLStringUtilBase<T>::copyInto(string_type& dst, const string_type& src, size_type offset)
{
if ( offset == dst.length() )
{
@@ -1092,7 +1493,7 @@ void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_s
}
else
{
- std::basic_string<T> tail = dst.substr(offset);
+ string_type tail = dst.substr(offset);
dst = dst.substr(0, offset);
dst += src;
@@ -1103,7 +1504,7 @@ void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_s
// True if this is the head of s.
//static
template<class T>
-BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s )
+BOOL LLStringUtilBase<T>::isHead( const string_type& string, const T* s )
{
if( string.empty() )
{
@@ -1119,8 +1520,8 @@ BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s
// static
template<class T>
bool LLStringUtilBase<T>::startsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr)
+ const string_type& string,
+ const string_type& substr)
{
if(string.empty() || (substr.empty())) return false;
if(0 == string.find(substr)) return true;
@@ -1130,8 +1531,8 @@ bool LLStringUtilBase<T>::startsWith(
// static
template<class T>
bool LLStringUtilBase<T>::endsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr)
+ const string_type& string,
+ const string_type& substr)
{
if(string.empty() || (substr.empty())) return false;
std::string::size_type idx = string.rfind(substr);
@@ -1141,14 +1542,14 @@ bool LLStringUtilBase<T>::endsWith(
template<class T>
-BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value)
+BOOL LLStringUtilBase<T>::convertToBOOL(const string_type& string, BOOL& value)
{
if( string.empty() )
{
return FALSE;
}
- std::basic_string<T> temp( string );
+ string_type temp( string );
trim(temp);
if(
(temp == "1") ||
@@ -1178,7 +1579,7 @@ BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToU8(const std::basic_string<T>& string, U8& value)
+BOOL LLStringUtilBase<T>::convertToU8(const string_type& string, U8& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1191,7 +1592,7 @@ BOOL LLStringUtilBase<T>::convertToU8(const std::basic_string<T>& string, U8& va
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToS8(const std::basic_string<T>& string, S8& value)
+BOOL LLStringUtilBase<T>::convertToS8(const string_type& string, S8& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1204,7 +1605,7 @@ BOOL LLStringUtilBase<T>::convertToS8(const std::basic_string<T>& string, S8& va
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToS16(const std::basic_string<T>& string, S16& value)
+BOOL LLStringUtilBase<T>::convertToS16(const string_type& string, S16& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1217,7 +1618,7 @@ BOOL LLStringUtilBase<T>::convertToS16(const std::basic_string<T>& string, S16&
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToU16(const std::basic_string<T>& string, U16& value)
+BOOL LLStringUtilBase<T>::convertToU16(const string_type& string, U16& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1230,17 +1631,17 @@ BOOL LLStringUtilBase<T>::convertToU16(const std::basic_string<T>& string, U16&
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToU32(const std::basic_string<T>& string, U32& value)
+BOOL LLStringUtilBase<T>::convertToU32(const string_type& string, U32& value)
{
if( string.empty() )
{
return FALSE;
}
- std::basic_string<T> temp( string );
+ string_type temp( string );
trim(temp);
U32 v;
- std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
+ std::basic_istringstream<T> i_stream((string_type)temp);
if(i_stream >> v)
{
value = v;
@@ -1250,17 +1651,17 @@ BOOL LLStringUtilBase<T>::convertToU32(const std::basic_string<T>& string, U32&
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToS32(const std::basic_string<T>& string, S32& value)
+BOOL LLStringUtilBase<T>::convertToS32(const string_type& string, S32& value)
{
if( string.empty() )
{
return FALSE;
}
- std::basic_string<T> temp( string );
+ string_type temp( string );
trim(temp);
S32 v;
- std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
+ std::basic_istringstream<T> i_stream((string_type)temp);
if(i_stream >> v)
{
//TODO: figure out overflow and underflow reporting here
@@ -1277,7 +1678,7 @@ BOOL LLStringUtilBase<T>::convertToS32(const std::basic_string<T>& string, S32&
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToF32(const std::basic_string<T>& string, F32& value)
+BOOL LLStringUtilBase<T>::convertToF32(const string_type& string, F32& value)
{
F64 value64 = 0.0;
BOOL success = convertToF64(string, value64);
@@ -1290,17 +1691,17 @@ BOOL LLStringUtilBase<T>::convertToF32(const std::basic_string<T>& string, F32&
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToF64(const std::basic_string<T>& string, F64& value)
+BOOL LLStringUtilBase<T>::convertToF64(const string_type& string, F64& value)
{
if( string.empty() )
{
return FALSE;
}
- std::basic_string<T> temp( string );
+ string_type temp( string );
trim(temp);
F64 v;
- std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
+ std::basic_istringstream<T> i_stream((string_type)temp);
if(i_stream >> v)
{
//TODO: figure out overflow and underflow reporting here
@@ -1317,7 +1718,7 @@ BOOL LLStringUtilBase<T>::convertToF64(const std::basic_string<T>& string, F64&
}
template<class T>
-void LLStringUtilBase<T>::truncate(std::basic_string<T>& string, size_type count)
+void LLStringUtilBase<T>::truncate(string_type& string, size_type count)
{
size_type cur_size = string.size();
string.resize(count < cur_size ? count : cur_size);
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 19075afa68..6073bcd0a6 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -1364,11 +1364,21 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */
if (! src) goto err;
- do
+ while ((bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE, src)) > 0)
{
- bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE,src);
- gzwrite(dst, buffer, bytes);
- } while(feof(src) == 0);
+ if (gzwrite(dst, buffer, bytes) <= 0)
+ {
+ llwarns << "gzwrite failed: " << gzerror(dst, NULL) << llendl;
+ goto err;
+ }
+ }
+
+ if (ferror(src))
+ {
+ llwarns << "Error reading " << srcfile << llendl;
+ goto err;
+ }
+
gzclose(dst);
dst = NULL;
#if LL_WINDOWS
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 4063cc730b..a6ad6b125c 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -337,11 +337,7 @@ LLMutex::~LLMutex()
void LLMutex::lock()
{
-#if LL_DARWIN
- if (mLockingThread == LLThread::currentID())
-#else
- if (mLockingThread == sThreadID)
-#endif
+ if(isSelfLocked())
{ //redundant lock
mCount++;
return;
@@ -398,6 +394,15 @@ bool LLMutex::isLocked()
}
}
+bool LLMutex::isSelfLocked()
+{
+#if LL_DARWIN
+ return mLockingThread == LLThread::currentID();
+#else
+ return mLockingThread == sThreadID;
+#endif
+}
+
U32 LLMutex::lockingThread() const
{
return mLockingThread;
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 40291a2569..b52e70ab2e 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -151,6 +151,7 @@ public:
void lock(); // blocks
void unlock();
bool isLocked(); // non-blocking, but does do a lock/unlock so not free
+ bool isSelfLocked(); //return true if locked in a same thread
U32 lockingThread() const; //get ID of locking thread
protected:
@@ -187,11 +188,14 @@ public:
LLMutexLock(LLMutex* mutex)
{
mMutex = mutex;
- mMutex->lock();
+
+ if(mMutex)
+ mMutex->lock();
}
~LLMutexLock()
{
- mMutex->unlock();
+ if(mMutex)
+ mMutex->unlock();
}
private:
LLMutex* mMutex;
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index ec378761c2..a869c74189 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -28,8 +28,8 @@
#define LL_LLVERSIONVIEWER_H
const S32 LL_VERSION_MAJOR = 3;
-const S32 LL_VERSION_MINOR = 2;
-const S32 LL_VERSION_PATCH = 6;
+const S32 LL_VERSION_MINOR = 3;
+const S32 LL_VERSION_PATCH = 0;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer";
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 4988bdf570..3d05a30ac2 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -81,7 +81,7 @@ void LLWorkerThread::clearDeleteList()
}
// virtual
-S32 LLWorkerThread::update(U32 max_time_ms)
+S32 LLWorkerThread::update(F32 max_time_ms)
{
S32 res = LLQueuedThread::update(max_time_ms);
// Delete scheduled workers
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index 78a4781d15..be46394d6e 100644
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
@@ -86,7 +86,7 @@ public:
LLWorkerThread(const std::string& name, bool threaded = true, bool should_pause = false);
~LLWorkerThread();
- /*virtual*/ S32 update(U32 max_time_ms);
+ /*virtual*/ S32 update(F32 max_time_ms);
handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL);
diff --git a/indra/llcommon/tests/StringVec.h b/indra/llcommon/tests/StringVec.h
new file mode 100644
index 0000000000..a380b00a05
--- /dev/null
+++ b/indra/llcommon/tests/StringVec.h
@@ -0,0 +1,37 @@
+/**
+ * @file StringVec.h
+ * @author Nat Goodspeed
+ * @date 2012-02-24
+ * @brief Extend TUT ensure_equals() to handle std::vector<std::string>
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_STRINGVEC_H)
+#define LL_STRINGVEC_H
+
+#include <vector>
+#include <string>
+#include <iostream>
+
+typedef std::vector<std::string> StringVec;
+
+std::ostream& operator<<(std::ostream& out, const StringVec& strings)
+{
+ out << '(';
+ StringVec::const_iterator begin(strings.begin()), end(strings.end());
+ if (begin != end)
+ {
+ out << '"' << *begin << '"';
+ while (++begin != end)
+ {
+ out << ", \"" << *begin << '"';
+ }
+ }
+ out << ')';
+ return out;
+}
+
+#endif /* ! defined(LL_STRINGVEC_H) */
diff --git a/indra/llcommon/tests/listener.h b/indra/llcommon/tests/listener.h
index dcdb2412be..9c5c18a150 100644
--- a/indra/llcommon/tests/listener.h
+++ b/indra/llcommon/tests/listener.h
@@ -30,6 +30,8 @@
#define LL_LISTENER_H
#include "llsd.h"
+#include "llevents.h"
+#include "tests/StringVec.h"
#include <iostream>
/*****************************************************************************
@@ -133,24 +135,7 @@ struct Collect
return false;
}
void clear() { result.clear(); }
- typedef std::vector<std::string> StringList;
- StringList result;
+ StringVec result;
};
-std::ostream& operator<<(std::ostream& out, const Collect::StringList& strings)
-{
- out << '(';
- Collect::StringList::const_iterator begin(strings.begin()), end(strings.end());
- if (begin != end)
- {
- out << '"' << *begin << '"';
- while (++begin != end)
- {
- out << ", \"" << *begin << '"';
- }
- }
- out << ')';
- return out;
-}
-
#endif /* ! defined(LL_LISTENER_H) */
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index fda932c355..454695ff9f 100644
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -112,6 +112,7 @@ namespace tut
void object::test<2>()
{
ensure_equals(Unkeyed::instanceCount(), 0);
+ Unkeyed* dangling = NULL;
{
Unkeyed one;
ensure_equals(Unkeyed::instanceCount(), 1);
@@ -124,7 +125,11 @@ namespace tut
ensure_equals(found, two.get());
}
ensure_equals(Unkeyed::instanceCount(), 1);
- }
+ // store an unwise pointer to a temp Unkeyed instance
+ dangling = &one;
+ } // make that instance vanish
+ // check the now-invalid pointer to the destroyed instance
+ ensure("getInstance(T*) failed to track destruction", ! Unkeyed::getInstance(dangling));
ensure_equals(Unkeyed::instanceCount(), 0);
}
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
new file mode 100644
index 0000000000..d7feddd26b
--- /dev/null
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -0,0 +1,1271 @@
+/**
+ * @file llprocess_test.cpp
+ * @author Nat Goodspeed
+ * @date 2011-12-19
+ * @brief Test for llprocess.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Copyright (c) 2011, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llprocess.h"
+// STL headers
+#include <vector>
+#include <list>
+// std headers
+#include <fstream>
+// external library headers
+#include "llapr.h"
+#include "apr_thread_proc.h"
+#include <boost/foreach.hpp>
+#include <boost/function.hpp>
+#include <boost/algorithm/string/find_iterator.hpp>
+#include <boost/algorithm/string/finder.hpp>
+//#include <boost/lambda/lambda.hpp>
+//#include <boost/lambda/bind.hpp>
+// other Linden headers
+#include "../test/lltut.h"
+#include "../test/manageapr.h"
+#include "../test/namedtempfile.h"
+#include "../test/catch_and_store_what_in.h"
+#include "stringize.h"
+#include "llsdutil.h"
+#include "llevents.h"
+#include "llerrorcontrol.h"
+
+#if defined(LL_WINDOWS)
+#define sleep(secs) _sleep((secs) * 1000)
+#define EOL "\r\n"
+#else
+#define EOL "\n"
+#include <sys/wait.h>
+#endif
+
+//namespace lambda = boost::lambda;
+
+// static instance of this manages APR init/cleanup
+static ManageAPR manager;
+
+/*****************************************************************************
+* Helpers
+*****************************************************************************/
+
+#define ensure_equals_(left, right) \
+ ensure_equals(STRINGIZE(#left << " != " << #right), (left), (right))
+
+#define aprchk(expr) aprchk_(#expr, (expr))
+static void aprchk_(const char* call, apr_status_t rv, apr_status_t expected=APR_SUCCESS)
+{
+ tut::ensure_equals(STRINGIZE(call << " => " << rv << ": " << manager.strerror(rv)),
+ rv, expected);
+}
+
+/**
+ * Read specified file using std::getline(). It is assumed to be an error if
+ * the file is empty: don't use this function if that's an acceptable case.
+ * Last line will not end with '\n'; this is to facilitate the usual case of
+ * string compares with a single line of output.
+ * @param pathname The file to read.
+ * @param desc Optional description of the file for error message;
+ * defaults to "in <pathname>"
+ */
+static std::string readfile(const std::string& pathname, const std::string& desc="")
+{
+ std::string use_desc(desc);
+ if (use_desc.empty())
+ {
+ use_desc = STRINGIZE("in " << pathname);
+ }
+ std::ifstream inf(pathname.c_str());
+ std::string output;
+ tut::ensure(STRINGIZE("No output " << use_desc), std::getline(inf, output));
+ std::string more;
+ while (std::getline(inf, more))
+ {
+ output += '\n' + more;
+ }
+ return output;
+}
+
+/// Looping on LLProcess::isRunning() must now be accompanied by pumping
+/// "mainloop" -- otherwise the status won't update and you get an infinite
+/// loop.
+void yield(int seconds=1)
+{
+ // This function simulates waiting for another viewer frame
+ sleep(seconds);
+ LLEventPumps::instance().obtain("mainloop").post(LLSD());
+}
+
+void waitfor(LLProcess& proc)
+{
+ while (proc.isRunning())
+ {
+ yield();
+ }
+}
+
+void waitfor(LLProcess::handle h, const std::string& desc)
+{
+ while (LLProcess::isRunning(h, desc))
+ {
+ yield();
+ }
+}
+
+/**
+ * Construct an LLProcess to run a Python script.
+ */
+struct PythonProcessLauncher
+{
+ /**
+ * @param desc Arbitrary description for error messages
+ * @param script Python script, any form acceptable to NamedTempFile,
+ * typically either a std::string or an expression of the form
+ * (lambda::_1 << "script content with " << variable_data)
+ */
+ template <typename CONTENT>
+ PythonProcessLauncher(const std::string& desc, const CONTENT& script):
+ mDesc(desc),
+ mScript("py", script)
+ {
+ const char* PYTHON(getenv("PYTHON"));
+ tut::ensure("Set $PYTHON to the Python interpreter", PYTHON);
+
+ mParams.desc = desc + " script";
+ mParams.executable = PYTHON;
+ mParams.args.add(mScript.getName());
+ }
+
+ /// Launch Python script; verify that it launched
+ void launch()
+ {
+ mPy = LLProcess::create(mParams);
+ tut::ensure(STRINGIZE("Couldn't launch " << mDesc << " script"), mPy);
+ }
+
+ /// Run Python script and wait for it to complete.
+ void run()
+ {
+ launch();
+ // One of the irritating things about LLProcess is that
+ // there's no API to wait for the child to terminate -- but given
+ // its use in our graphics-intensive interactive viewer, it's
+ // understandable.
+ waitfor(*mPy);
+ }
+
+ /**
+ * Run a Python script using LLProcess, expecting that it will
+ * write to the file passed as its sys.argv[1]. Retrieve that output.
+ *
+ * Until January 2012, LLProcess provided distressingly few
+ * mechanisms for a child process to communicate back to its caller --
+ * not even its return code. We've introduced a convention by which we
+ * create an empty temp file, pass the name of that file to our child
+ * as sys.argv[1] and expect the script to write its output to that
+ * file. This function implements the C++ (parent process) side of
+ * that convention.
+ */
+ std::string run_read()
+ {
+ NamedTempFile out("out", ""); // placeholder
+ // pass name of this temporary file to the script
+ mParams.args.add(out.getName());
+ run();
+ // assuming the script wrote to that file, read it
+ return readfile(out.getName(), STRINGIZE("from " << mDesc << " script"));
+ }
+
+ LLProcess::Params mParams;
+ LLProcessPtr mPy;
+ std::string mDesc;
+ NamedTempFile mScript;
+};
+
+/// convenience function for PythonProcessLauncher::run()
+template <typename CONTENT>
+static void python(const std::string& desc, const CONTENT& script)
+{
+ PythonProcessLauncher py(desc, script);
+ py.run();
+}
+
+/// convenience function for PythonProcessLauncher::run_read()
+template <typename CONTENT>
+static std::string python_out(const std::string& desc, const CONTENT& script)
+{
+ PythonProcessLauncher py(desc, script);
+ return py.run_read();
+}
+
+/// Create a temporary directory and clean it up later.
+class NamedTempDir: public boost::noncopyable
+{
+public:
+ // Use python() function to create a temp directory: I've found
+ // nothing in either Boost.Filesystem or APR quite like Python's
+ // tempfile.mkdtemp().
+ // Special extra bonus: on Mac, mkdtemp() reports a pathname
+ // starting with /var/folders/something, whereas that's really a
+ // symlink to /private/var/folders/something. Have to use
+ // realpath() to compare properly.
+ NamedTempDir():
+ mPath(python_out("mkdtemp()",
+ "from __future__ import with_statement\n"
+ "import os.path, sys, tempfile\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write(os.path.normcase(os.path.normpath(os.path.realpath(tempfile.mkdtemp()))))\n"))
+ {}
+
+ ~NamedTempDir()
+ {
+ aprchk(apr_dir_remove(mPath.c_str(), gAPRPoolp));
+ }
+
+ std::string getName() const { return mPath; }
+
+private:
+ std::string mPath;
+};
+
+// statically reference the function in test.cpp... it's short, we could
+// replicate, but better to reuse
+extern void wouldHaveCrashed(const std::string& message);
+
+/**
+ * Capture log messages. This is adapted (simplified) from the one in
+ * llerror_test.cpp. Sigh, should've broken that out into a separate header
+ * file, but time for this project is short...
+ */
+class TestRecorder : public LLError::Recorder
+{
+public:
+ TestRecorder():
+ // Mostly what we're trying to accomplish by saving and resetting
+ // LLError::Settings is to bypass the default RecordToStderr and
+ // RecordToWinDebug Recorders. As these are visible only inside
+ // llerror.cpp, we can't just call LLError::removeRecorder() with
+ // each. For certain tests we need to produce, capture and examine
+ // DEBUG log messages -- but we don't want to spam the user's console
+ // with that output. If it turns out that saveAndResetSettings() has
+ // some bad effect, give up and just let the DEBUG level log messages
+ // display.
+ mOldSettings(LLError::saveAndResetSettings())
+ {
+ LLError::setFatalFunction(wouldHaveCrashed);
+ LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
+ LLError::addRecorder(this);
+ }
+
+ ~TestRecorder()
+ {
+ LLError::removeRecorder(this);
+ LLError::restoreSettings(mOldSettings);
+ }
+
+ void recordMessage(LLError::ELevel level,
+ const std::string& message)
+ {
+ mMessages.push_back(message);
+ }
+
+ /// Don't assume the message we want is necessarily the LAST log message
+ /// emitted by the underlying code; search backwards through all messages
+ /// for the sought string.
+ std::string messageWith(const std::string& search)
+ {
+ for (std::list<std::string>::const_reverse_iterator rmi(mMessages.rbegin()),
+ rmend(mMessages.rend());
+ rmi != rmend; ++rmi)
+ {
+ if (rmi->find(search) != std::string::npos)
+ return *rmi;
+ }
+ // failed to find any such message
+ return std::string();
+ }
+
+ typedef std::list<std::string> MessageList;
+ MessageList mMessages;
+ LLError::Settings* mOldSettings;
+};
+
+std::string getline(std::istream& in)
+{
+ std::string line;
+ std::getline(in, line);
+ // Blur the distinction between "\r\n" and plain "\n". std::getline() will
+ // have eaten the "\n", but we could still end up with a trailing "\r".
+ std::string::size_type lastpos = line.find_last_not_of("\r");
+ if (lastpos != std::string::npos)
+ {
+ // Found at least one character that's not a trailing '\r'. SKIP OVER
+ // IT and then erase the rest of the line.
+ line.erase(lastpos+1);
+ }
+ return line;
+}
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct llprocess_data
+ {
+ LLAPRPool pool;
+ };
+ typedef test_group<llprocess_data> llprocess_group;
+ typedef llprocess_group::object object;
+ llprocess_group llprocessgrp("llprocess");
+
+ struct Item
+ {
+ Item(): tries(0) {}
+ unsigned tries;
+ std::string which;
+ std::string what;
+ };
+
+/*==========================================================================*|
+#define tabent(symbol) { symbol, #symbol }
+ static struct ReasonCode
+ {
+ int code;
+ const char* name;
+ } reasons[] =
+ {
+ tabent(APR_OC_REASON_DEATH),
+ tabent(APR_OC_REASON_UNWRITABLE),
+ tabent(APR_OC_REASON_RESTART),
+ tabent(APR_OC_REASON_UNREGISTER),
+ tabent(APR_OC_REASON_LOST),
+ tabent(APR_OC_REASON_RUNNING)
+ };
+#undef tabent
+|*==========================================================================*/
+
+ struct WaitInfo
+ {
+ WaitInfo(apr_proc_t* child_):
+ child(child_),
+ rv(-1), // we haven't yet called apr_proc_wait()
+ rc(0),
+ why(apr_exit_why_e(0))
+ {}
+ apr_proc_t* child; // which subprocess
+ apr_status_t rv; // return from apr_proc_wait()
+ int rc; // child's exit code
+ apr_exit_why_e why; // APR_PROC_EXIT, APR_PROC_SIGNAL, APR_PROC_SIGNAL_CORE
+ };
+
+ void child_status_callback(int reason, void* data, int status)
+ {
+/*==========================================================================*|
+ std::string reason_str;
+ BOOST_FOREACH(const ReasonCode& rcp, reasons)
+ {
+ if (reason == rcp.code)
+ {
+ reason_str = rcp.name;
+ break;
+ }
+ }
+ if (reason_str.empty())
+ {
+ reason_str = STRINGIZE("unknown reason " << reason);
+ }
+ std::cout << "child_status_callback(" << reason_str << ")\n";
+|*==========================================================================*/
+
+ if (reason == APR_OC_REASON_DEATH || reason == APR_OC_REASON_LOST)
+ {
+ // Somewhat oddly, APR requires that you explicitly unregister
+ // even when it already knows the child has terminated.
+ apr_proc_other_child_unregister(data);
+
+ WaitInfo* wi(static_cast<WaitInfo*>(data));
+ // It's just wrong to call apr_proc_wait() here. The only way APR
+ // knows to call us with APR_OC_REASON_DEATH is that it's already
+ // reaped this child process, so calling wait() will only produce
+ // "huh?" from the OS. We must rely on the status param passed in,
+ // which unfortunately comes straight from the OS wait() call.
+// wi->rv = apr_proc_wait(wi->child, &wi->rc, &wi->why, APR_NOWAIT);
+ wi->rv = APR_CHILD_DONE; // fake apr_proc_wait() results
+#if defined(LL_WINDOWS)
+ wi->why = APR_PROC_EXIT;
+ wi->rc = status; // no encoding on Windows (no signals)
+#else // Posix
+ if (WIFEXITED(status))
+ {
+ wi->why = APR_PROC_EXIT;
+ wi->rc = WEXITSTATUS(status);
+ }
+ else if (WIFSIGNALED(status))
+ {
+ wi->why = APR_PROC_SIGNAL;
+ wi->rc = WTERMSIG(status);
+ }
+ else // uh, shouldn't happen?
+ {
+ wi->why = APR_PROC_EXIT;
+ wi->rc = status; // someone else will have to decode
+ }
+#endif // Posix
+ }
+ }
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("raw APR nonblocking I/O");
+
+ // Create a script file in a temporary place.
+ NamedTempFile script("py",
+ "import sys" EOL
+ "import time" EOL
+ EOL
+ "time.sleep(2)" EOL
+ "print >>sys.stdout, 'stdout after wait'" EOL
+ "sys.stdout.flush()" EOL
+ "time.sleep(2)" EOL
+ "print >>sys.stderr, 'stderr after wait'" EOL
+ "sys.stderr.flush()" EOL
+ );
+
+ // Arrange to track the history of our interaction with child: what we
+ // fetched, which pipe it came from, how many tries it took before we
+ // got it.
+ std::vector<Item> history;
+ history.push_back(Item());
+
+ // Run the child process.
+ apr_procattr_t *procattr = NULL;
+ aprchk(apr_procattr_create(&procattr, pool.getAPRPool()));
+ aprchk(apr_procattr_io_set(procattr, APR_CHILD_BLOCK, APR_CHILD_BLOCK, APR_CHILD_BLOCK));
+ aprchk(apr_procattr_cmdtype_set(procattr, APR_PROGRAM_PATH));
+
+ std::vector<const char*> argv;
+ apr_proc_t child;
+ argv.push_back("python");
+ // Have to have a named copy of this std::string so its c_str() value
+ // will persist.
+ std::string scriptname(script.getName());
+ argv.push_back(scriptname.c_str());
+ argv.push_back(NULL);
+
+ aprchk(apr_proc_create(&child, argv[0],
+ &argv[0],
+ NULL, // if we wanted to pass explicit environment
+ procattr,
+ pool.getAPRPool()));
+
+ // We do not want this child process to outlive our APR pool. On
+ // destruction of the pool, forcibly kill the process. Tell APR to try
+ // SIGTERM and wait 3 seconds. If that didn't work, use SIGKILL.
+ apr_pool_note_subprocess(pool.getAPRPool(), &child, APR_KILL_AFTER_TIMEOUT);
+
+ // arrange to call child_status_callback()
+ WaitInfo wi(&child);
+ apr_proc_other_child_register(&child, child_status_callback, &wi, child.in, pool.getAPRPool());
+
+ // TODO:
+ // Stuff child.in until it (would) block to verify EWOULDBLOCK/EAGAIN.
+ // Have child script clear it later, then write one more line to prove
+ // that it gets through.
+
+ // Monitor two different output pipes. Because one will be closed
+ // before the other, keep them in a list so we can drop whichever of
+ // them is closed first.
+ typedef std::pair<std::string, apr_file_t*> DescFile;
+ typedef std::list<DescFile> DescFileList;
+ DescFileList outfiles;
+ outfiles.push_back(DescFile("out", child.out));
+ outfiles.push_back(DescFile("err", child.err));
+
+ while (! outfiles.empty())
+ {
+ // This peculiar for loop is designed to let us erase(dfli). With
+ // a list, that invalidates only dfli itself -- but even so, we
+ // lose the ability to increment it for the next item. So at the
+ // top of every loop, while dfli is still valid, increment
+ // dflnext. Then before the next iteration, set dfli to dflnext.
+ for (DescFileList::iterator
+ dfli(outfiles.begin()), dflnext(outfiles.begin()), dflend(outfiles.end());
+ dfli != dflend; dfli = dflnext)
+ {
+ // Only valid to increment dflnext once we're sure it's not
+ // already at dflend.
+ ++dflnext;
+
+ char buf[4096];
+
+ apr_status_t rv = apr_file_gets(buf, sizeof(buf), dfli->second);
+ if (APR_STATUS_IS_EOF(rv))
+ {
+// std::cout << "(EOF on " << dfli->first << ")\n";
+// history.back().which = dfli->first;
+// history.back().what = "*eof*";
+// history.push_back(Item());
+ outfiles.erase(dfli);
+ continue;
+ }
+ if (rv == EWOULDBLOCK || rv == EAGAIN)
+ {
+// std::cout << "(waiting; apr_file_gets(" << dfli->first << ") => " << rv << ": " << manager.strerror(rv) << ")\n";
+ ++history.back().tries;
+ continue;
+ }
+ aprchk_("apr_file_gets(buf, sizeof(buf), dfli->second)", rv);
+ // Is it even possible to get APR_SUCCESS but read 0 bytes?
+ // Hope not, but defend against that anyway.
+ if (buf[0])
+ {
+// std::cout << dfli->first << ": " << buf;
+ history.back().which = dfli->first;
+ history.back().what.append(buf);
+ if (buf[strlen(buf) - 1] == '\n')
+ history.push_back(Item());
+ else
+ {
+ // Just for pretty output... if we only read a partial
+ // line, terminate it.
+// std::cout << "...\n";
+ }
+ }
+ }
+ // Do this once per tick, as we expect the viewer will
+ apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING);
+ sleep(1);
+ }
+ apr_file_close(child.in);
+ apr_file_close(child.out);
+ apr_file_close(child.err);
+
+ // Okay, we've broken the loop because our pipes are all closed. If we
+ // haven't yet called wait, give the callback one more chance. This
+ // models the fact that unlike this small test program, the viewer
+ // will still be running.
+ if (wi.rv == -1)
+ {
+ std::cout << "last gasp apr_proc_other_child_refresh_all()\n";
+ apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING);
+ }
+
+ if (wi.rv == -1)
+ {
+ std::cout << "child_status_callback(APR_OC_REASON_DEATH) wasn't called" << std::endl;
+ wi.rv = apr_proc_wait(wi.child, &wi.rc, &wi.why, APR_NOWAIT);
+ }
+// std::cout << "child done: rv = " << rv << " (" << manager.strerror(rv) << "), why = " << why << ", rc = " << rc << '\n';
+ aprchk_("apr_proc_wait(wi->child, &wi->rc, &wi->why, APR_NOWAIT)", wi.rv, APR_CHILD_DONE);
+ ensure_equals_(wi.why, APR_PROC_EXIT);
+ ensure_equals_(wi.rc, 0);
+
+ // Beyond merely executing all the above successfully, verify that we
+ // obtained expected output -- and that we duly got control while
+ // waiting, proving the non-blocking nature of these pipes.
+ try
+ {
+ unsigned i = 0;
+ ensure("blocking I/O on child pipe (0)", history[i].tries);
+ ensure_equals_(history[i].which, "out");
+ ensure_equals_(history[i].what, "stdout after wait" EOL);
+// ++i;
+// ensure_equals_(history[i].which, "out");
+// ensure_equals_(history[i].what, "*eof*");
+ ++i;
+ ensure("blocking I/O on child pipe (1)", history[i].tries);
+ ensure_equals_(history[i].which, "err");
+ ensure_equals_(history[i].what, "stderr after wait" EOL);
+// ++i;
+// ensure_equals_(history[i].which, "err");
+// ensure_equals_(history[i].what, "*eof*");
+ }
+ catch (const failure&)
+ {
+ std::cout << "History:\n";
+ BOOST_FOREACH(const Item& item, history)
+ {
+ std::string what(item.what);
+ if ((! what.empty()) && what[what.length() - 1] == '\n')
+ {
+ what.erase(what.length() - 1);
+ if ((! what.empty()) && what[what.length() - 1] == '\r')
+ {
+ what.erase(what.length() - 1);
+ what.append("\\r");
+ }
+ what.append("\\n");
+ }
+ std::cout << " " << item.which << ": '" << what << "' ("
+ << item.tries << " tries)\n";
+ }
+ std::cout << std::flush;
+ // re-raise same error; just want to enrich the output
+ throw;
+ }
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ set_test_name("setWorkingDirectory()");
+ // We want to test setWorkingDirectory(). But what directory is
+ // guaranteed to exist on every machine, under every OS? Have to
+ // create one. Naturally, ensure we clean it up when done.
+ NamedTempDir tempdir;
+ PythonProcessLauncher py("getcwd()",
+ "from __future__ import with_statement\n"
+ "import os, sys\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write(os.path.normcase(os.path.normpath(os.getcwd())))\n");
+ // Before running, call setWorkingDirectory()
+ py.mParams.cwd = tempdir.getName();
+ ensure_equals("os.getcwd()", py.run_read(), tempdir.getName());
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ set_test_name("arguments");
+ PythonProcessLauncher py("args",
+ "from __future__ import with_statement\n"
+ "import sys\n"
+ // note nonstandard output-file arg!
+ "with open(sys.argv[3], 'w') as f:\n"
+ " for arg in sys.argv[1:]:\n"
+ " print >>f, arg\n");
+ // We expect that PythonProcessLauncher has already appended
+ // its own NamedTempFile to mParams.args (sys.argv[0]).
+ py.mParams.args.add("first arg"); // sys.argv[1]
+ py.mParams.args.add("second arg"); // sys.argv[2]
+ // run_read() appends() one more argument, hence [3]
+ std::string output(py.run_read());
+ boost::split_iterator<std::string::const_iterator>
+ li(output, boost::first_finder("\n")), lend;
+ ensure("didn't get first arg", li != lend);
+ std::string arg(li->begin(), li->end());
+ ensure_equals(arg, "first arg");
+ ++li;
+ ensure("didn't get second arg", li != lend);
+ arg.assign(li->begin(), li->end());
+ ensure_equals(arg, "second arg");
+ ++li;
+ ensure("didn't get output filename?!", li != lend);
+ arg.assign(li->begin(), li->end());
+ ensure("output filename empty?!", ! arg.empty());
+ ++li;
+ ensure("too many args", li == lend);
+ }
+
+ template<> template<>
+ void object::test<4>()
+ {
+ set_test_name("exit(0)");
+ PythonProcessLauncher py("exit(0)",
+ "import sys\n"
+ "sys.exit(0)\n");
+ py.run();
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, 0);
+ }
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("exit(2)");
+ PythonProcessLauncher py("exit(2)",
+ "import sys\n"
+ "sys.exit(2)\n");
+ py.run();
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, 2);
+ }
+
+ template<> template<>
+ void object::test<6>()
+ {
+ set_test_name("syntax_error:");
+ PythonProcessLauncher py("syntax_error:",
+ "syntax_error:\n");
+ py.mParams.files.add(LLProcess::FileParam()); // inherit stdin
+ py.mParams.files.add(LLProcess::FileParam()); // inherit stdout
+ py.mParams.files.add(LLProcess::FileParam().type("pipe")); // pipe for stderr
+ py.run();
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, 1);
+ std::istream& rpipe(py.mPy->getReadPipe(LLProcess::STDERR).get_istream());
+ std::vector<char> buffer(4096);
+ rpipe.read(&buffer[0], buffer.size());
+ std::streamsize got(rpipe.gcount());
+ ensure("Nothing read from stderr pipe", got);
+ std::string data(&buffer[0], got);
+ ensure("Didn't find 'SyntaxError:'", data.find("\nSyntaxError:") != std::string::npos);
+ }
+
+ template<> template<>
+ void object::test<7>()
+ {
+ set_test_name("explicit kill()");
+ PythonProcessLauncher py("kill()",
+ "from __future__ import with_statement\n"
+ "import sys, time\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('ok')\n"
+ "# now sleep; expect caller to kill\n"
+ "time.sleep(120)\n"
+ "# if caller hasn't managed to kill by now, bad\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('bad')\n");
+ NamedTempFile out("out", "not started");
+ py.mParams.args.add(out.getName());
+ py.launch();
+ // Wait for the script to wake up and do its first write
+ int i = 0, timeout = 60;
+ for ( ; i < timeout; ++i)
+ {
+ yield();
+ if (readfile(out.getName(), "from kill() script") == "ok")
+ break;
+ }
+ // If we broke this loop because of the counter, something's wrong
+ ensure("script never started", i < timeout);
+ // script has performed its first write and should now be sleeping.
+ py.mPy->kill();
+ // wait for the script to terminate... one way or another.
+ waitfor(*py.mPy);
+#if LL_WINDOWS
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, -1);
+#else
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::KILLED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, SIGTERM);
+#endif
+ // If kill() failed, the script would have woken up on its own and
+ // overwritten the file with 'bad'. But if kill() succeeded, it should
+ // not have had that chance.
+ ensure_equals("kill() script output", readfile(out.getName()), "ok");
+ }
+
+ template<> template<>
+ void object::test<8>()
+ {
+ set_test_name("implicit kill()");
+ NamedTempFile out("out", "not started");
+ LLProcess::handle phandle(0);
+ {
+ PythonProcessLauncher py("kill()",
+ "from __future__ import with_statement\n"
+ "import sys, time\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('ok')\n"
+ "# now sleep; expect caller to kill\n"
+ "time.sleep(120)\n"
+ "# if caller hasn't managed to kill by now, bad\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('bad')\n");
+ py.mParams.args.add(out.getName());
+ py.launch();
+ // Capture handle for later
+ phandle = py.mPy->getProcessHandle();
+ // Wait for the script to wake up and do its first write
+ int i = 0, timeout = 60;
+ for ( ; i < timeout; ++i)
+ {
+ yield();
+ if (readfile(out.getName(), "from kill() script") == "ok")
+ break;
+ }
+ // If we broke this loop because of the counter, something's wrong
+ ensure("script never started", i < timeout);
+ // Script has performed its first write and should now be sleeping.
+ // Destroy the LLProcess, which should kill the child.
+ }
+ // wait for the script to terminate... one way or another.
+ waitfor(phandle, "kill() script");
+ // If kill() failed, the script would have woken up on its own and
+ // overwritten the file with 'bad'. But if kill() succeeded, it should
+ // not have had that chance.
+ ensure_equals("kill() script output", readfile(out.getName()), "ok");
+ }
+
+ template<> template<>
+ void object::test<9>()
+ {
+ set_test_name("autokill=false");
+ NamedTempFile from("from", "not started");
+ NamedTempFile to("to", "");
+ LLProcess::handle phandle(0);
+ {
+ PythonProcessLauncher py("autokill",
+ "from __future__ import with_statement\n"
+ "import sys, time\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('ok')\n"
+ "# wait for 'go' from test program\n"
+ "for i in xrange(60):\n"
+ " time.sleep(1)\n"
+ " with open(sys.argv[2]) as f:\n"
+ " go = f.read()\n"
+ " if go == 'go':\n"
+ " break\n"
+ "else:\n"
+ " with open(sys.argv[1], 'w') as f:\n"
+ " f.write('never saw go')\n"
+ " sys.exit(1)\n"
+ "# okay, saw 'go', write 'ack'\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('ack')\n");
+ py.mParams.args.add(from.getName());
+ py.mParams.args.add(to.getName());
+ py.mParams.autokill = false;
+ py.launch();
+ // Capture handle for later
+ phandle = py.mPy->getProcessHandle();
+ // Wait for the script to wake up and do its first write
+ int i = 0, timeout = 60;
+ for ( ; i < timeout; ++i)
+ {
+ yield();
+ if (readfile(from.getName(), "from autokill script") == "ok")
+ break;
+ }
+ // If we broke this loop because of the counter, something's wrong
+ ensure("script never started", i < timeout);
+ // Now destroy the LLProcess, which should NOT kill the child!
+ }
+ // If the destructor killed the child anyway, give it time to die
+ yield(2);
+ // How do we know it's not terminated? By making it respond to
+ // a specific stimulus in a specific way.
+ {
+ std::ofstream outf(to.getName().c_str());
+ outf << "go";
+ } // flush and close.
+ // now wait for the script to terminate... one way or another.
+ waitfor(phandle, "autokill script");
+ // If the LLProcess destructor implicitly called kill(), the
+ // script could not have written 'ack' as we expect.
+ ensure_equals("autokill script output", readfile(from.getName()), "ack");
+ }
+
+ template<> template<>
+ void object::test<10>()
+ {
+ set_test_name("'bogus' test");
+ TestRecorder recorder;
+ PythonProcessLauncher py("'bogus' test",
+ "print 'Hello world'\n");
+ py.mParams.files.add(LLProcess::FileParam("bogus"));
+ py.mPy = LLProcess::create(py.mParams);
+ ensure("should have rejected 'bogus'", ! py.mPy);
+ std::string message(recorder.messageWith("bogus"));
+ ensure("did not log 'bogus' type", ! message.empty());
+ ensure_contains("did not name 'stdin'", message, "stdin");
+ }
+
+ template<> template<>
+ void object::test<11>()
+ {
+ set_test_name("'file' test");
+ // Replace this test with one or more real 'file' tests when we
+ // implement 'file' support
+ PythonProcessLauncher py("'file' test",
+ "print 'Hello world'\n");
+ py.mParams.files.add(LLProcess::FileParam());
+ py.mParams.files.add(LLProcess::FileParam("file"));
+ py.mPy = LLProcess::create(py.mParams);
+ ensure("should have rejected 'file'", ! py.mPy);
+ }
+
+ template<> template<>
+ void object::test<12>()
+ {
+ set_test_name("'tpipe' test");
+ // Replace this test with one or more real 'tpipe' tests when we
+ // implement 'tpipe' support
+ TestRecorder recorder;
+ PythonProcessLauncher py("'tpipe' test",
+ "print 'Hello world'\n");
+ py.mParams.files.add(LLProcess::FileParam());
+ py.mParams.files.add(LLProcess::FileParam("tpipe"));
+ py.mPy = LLProcess::create(py.mParams);
+ ensure("should have rejected 'tpipe'", ! py.mPy);
+ std::string message(recorder.messageWith("tpipe"));
+ ensure("did not log 'tpipe' type", ! message.empty());
+ ensure_contains("did not name 'stdout'", message, "stdout");
+ }
+
+ template<> template<>
+ void object::test<13>()
+ {
+ set_test_name("'npipe' test");
+ // Replace this test with one or more real 'npipe' tests when we
+ // implement 'npipe' support
+ TestRecorder recorder;
+ PythonProcessLauncher py("'npipe' test",
+ "print 'Hello world'\n");
+ py.mParams.files.add(LLProcess::FileParam());
+ py.mParams.files.add(LLProcess::FileParam());
+ py.mParams.files.add(LLProcess::FileParam("npipe"));
+ py.mPy = LLProcess::create(py.mParams);
+ ensure("should have rejected 'npipe'", ! py.mPy);
+ std::string message(recorder.messageWith("npipe"));
+ ensure("did not log 'npipe' type", ! message.empty());
+ ensure_contains("did not name 'stderr'", message, "stderr");
+ }
+
+ template<> template<>
+ void object::test<14>()
+ {
+ set_test_name("internal pipe name warning");
+ TestRecorder recorder;
+ PythonProcessLauncher py("pipe warning",
+ "import sys\n"
+ "sys.exit(7)\n");
+ py.mParams.files.add(LLProcess::FileParam("pipe", "somename"));
+ py.run(); // verify that it did launch anyway
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, 7);
+ std::string message(recorder.messageWith("not yet supported"));
+ ensure("did not log pipe name warning", ! message.empty());
+ ensure_contains("log message did not mention internal pipe name",
+ message, "somename");
+ }
+
+ /*-------------- support for "get*Pipe() validation" test --------------*/
+#define TEST_getPipe(PROCESS, GETPIPE, GETOPTPIPE, VALID, NOPIPE, BADPIPE) \
+ do \
+ { \
+ std::string threw; \
+ /* Both the following calls should work. */ \
+ (PROCESS).GETPIPE(VALID); \
+ ensure(#GETOPTPIPE "(" #VALID ") failed", (PROCESS).GETOPTPIPE(VALID)); \
+ /* pass obviously bogus PIPESLOT */ \
+ CATCH_IN(threw, LLProcess::NoPipe, (PROCESS).GETPIPE(LLProcess::FILESLOT(4))); \
+ ensure_contains("didn't reject bad slot", threw, "no slot"); \
+ ensure_contains("didn't mention bad slot num", threw, "4"); \
+ EXPECT_FAIL_WITH_LOG(threw, (PROCESS).GETOPTPIPE(LLProcess::FILESLOT(4))); \
+ /* pass NOPIPE */ \
+ CATCH_IN(threw, LLProcess::NoPipe, (PROCESS).GETPIPE(NOPIPE)); \
+ ensure_contains("didn't reject non-pipe", threw, "not a monitored"); \
+ EXPECT_FAIL_WITH_LOG(threw, (PROCESS).GETOPTPIPE(NOPIPE)); \
+ /* pass BADPIPE: FILESLOT isn't empty but wrong direction */ \
+ CATCH_IN(threw, LLProcess::NoPipe, (PROCESS).GETPIPE(BADPIPE)); \
+ /* sneaky: GETPIPE is getReadPipe or getWritePipe */ \
+ /* so skip "get" to obtain ReadPipe or WritePipe :-P */ \
+ ensure_contains("didn't reject wrong pipe", threw, (#GETPIPE)+3); \
+ EXPECT_FAIL_WITH_LOG(threw, (PROCESS).GETOPTPIPE(BADPIPE)); \
+ } while (0)
+
+/// For expecting exceptions. Execute CODE, catch EXCEPTION, store its what()
+/// in std::string THREW, ensure it's not empty (i.e. EXCEPTION did happen).
+#define CATCH_IN(THREW, EXCEPTION, CODE) \
+ do \
+ { \
+ (THREW).clear(); \
+ try \
+ { \
+ CODE; \
+ } \
+ CATCH_AND_STORE_WHAT_IN(THREW, EXCEPTION) \
+ ensure("failed to throw " #EXCEPTION ": " #CODE, ! (THREW).empty()); \
+ } while (0)
+
+#define EXPECT_FAIL_WITH_LOG(EXPECT, CODE) \
+ do \
+ { \
+ TestRecorder recorder; \
+ ensure(#CODE " succeeded", ! (CODE)); \
+ ensure("wrong log message", ! recorder.messageWith(EXPECT).empty()); \
+ } while (0)
+
+ template<> template<>
+ void object::test<15>()
+ {
+ set_test_name("get*Pipe() validation");
+ PythonProcessLauncher py("just stderr",
+ "print 'this output is expected'\n");
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stdin
+ py.mParams.files.add(LLProcess::FileParam()); // inherit stdout
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stderr
+ py.run();
+ TEST_getPipe(*py.mPy, getWritePipe, getOptWritePipe,
+ LLProcess::STDIN, // VALID
+ LLProcess::STDOUT, // NOPIPE
+ LLProcess::STDERR); // BADPIPE
+ TEST_getPipe(*py.mPy, getReadPipe, getOptReadPipe,
+ LLProcess::STDERR, // VALID
+ LLProcess::STDOUT, // NOPIPE
+ LLProcess::STDIN); // BADPIPE
+ }
+
+ template<> template<>
+ void object::test<16>()
+ {
+ set_test_name("talk to stdin/stdout");
+ PythonProcessLauncher py("stdin/stdout",
+ "import sys, time\n"
+ "print 'ok'\n"
+ "sys.stdout.flush()\n"
+ "# wait for 'go' from test program\n"
+ "go = sys.stdin.readline()\n"
+ "if go != 'go\\n':\n"
+ " sys.exit('expected \"go\", saw %r' % go)\n"
+ "print 'ack'\n");
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdin
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
+ py.launch();
+ LLProcess::ReadPipe& childout(py.mPy->getReadPipe(LLProcess::STDOUT));
+ int i, timeout = 60;
+ for (i = 0; i < timeout && py.mPy->isRunning() && childout.size() < 3; ++i)
+ {
+ yield();
+ }
+ ensure("script never started", i < timeout);
+ ensure_equals("bad wakeup from stdin/stdout script",
+ getline(childout.get_istream()), "ok");
+ // important to get the implicit flush from std::endl
+ py.mPy->getWritePipe().get_ostream() << "go" << std::endl;
+ for (i = 0; i < timeout && py.mPy->isRunning() && ! childout.contains("\n"); ++i)
+ {
+ yield();
+ }
+ ensure("script never replied", childout.contains("\n"));
+ ensure_equals("child didn't ack", getline(childout.get_istream()), "ack");
+ ensure_equals("bad child termination", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("bad child exit code", py.mPy->getStatus().mData, 0);
+ }
+
+ struct EventListener: public boost::noncopyable
+ {
+ EventListener(LLEventPump& pump)
+ {
+ mConnection =
+ pump.listen("EventListener", boost::bind(&EventListener::tick, this, _1));
+ }
+
+ bool tick(const LLSD& data)
+ {
+ mHistory.push_back(data);
+ return false;
+ }
+
+ std::list<LLSD> mHistory;
+ LLTempBoundListener mConnection;
+ };
+
+ static bool ack(std::ostream& out, const LLSD& data)
+ {
+ out << "continue" << std::endl;
+ return false;
+ }
+
+ template<> template<>
+ void object::test<17>()
+ {
+ set_test_name("listen for ReadPipe events");
+ PythonProcessLauncher py("ReadPipe listener",
+ "import sys\n"
+ "sys.stdout.write('abc')\n"
+ "sys.stdout.flush()\n"
+ "sys.stdin.readline()\n"
+ "sys.stdout.write('def')\n"
+ "sys.stdout.flush()\n"
+ "sys.stdin.readline()\n"
+ "sys.stdout.write('ghi\\n')\n"
+ "sys.stdout.flush()\n"
+ "sys.stdin.readline()\n"
+ "sys.stdout.write('second line\\n')\n");
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdin
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
+ py.launch();
+ std::ostream& childin(py.mPy->getWritePipe(LLProcess::STDIN).get_ostream());
+ LLProcess::ReadPipe& childout(py.mPy->getReadPipe(LLProcess::STDOUT));
+ // lift the default limit; allow event to carry (some of) the actual data
+ childout.setLimit(20);
+ // listen for incoming data on childout
+ EventListener listener(childout.getPump());
+ // also listen with a function that prompts the child to continue
+ // every time we see output
+ LLTempBoundListener connection(
+ childout.getPump().listen("ack", boost::bind(ack, boost::ref(childin), _1)));
+ int i, timeout = 60;
+ // wait through stuttering first line
+ for (i = 0; i < timeout && py.mPy->isRunning() && ! childout.contains("\n"); ++i)
+ {
+ yield();
+ }
+ ensure("couldn't get first line", i < timeout);
+ // disconnect from listener
+ listener.mConnection.disconnect();
+ // finish out the run
+ waitfor(*py.mPy);
+ // now verify history
+ std::list<LLSD>::const_iterator li(listener.mHistory.begin()),
+ lend(listener.mHistory.end());
+ ensure("no events", li != lend);
+ ensure_equals("history[0]", (*li)["data"].asString(), "abc");
+ ensure_equals("history[0] len", (*li)["len"].asInteger(), 3);
+ ++li;
+ ensure("only 1 event", li != lend);
+ ensure_equals("history[1]", (*li)["data"].asString(), "abcdef");
+ ensure_equals("history[0] len", (*li)["len"].asInteger(), 6);
+ ++li;
+ ensure("only 2 events", li != lend);
+ ensure_equals("history[2]", (*li)["data"].asString(), "abcdefghi" EOL);
+ ensure_equals("history[0] len", (*li)["len"].asInteger(), 9 + sizeof(EOL) - 1);
+ ++li;
+ // We DO NOT expect a whole new event for the second line because we
+ // disconnected.
+ ensure("more than 3 events", li == lend);
+ }
+
+ template<> template<>
+ void object::test<18>()
+ {
+ set_test_name("setLimit()");
+ PythonProcessLauncher py("setLimit()",
+ "import sys\n"
+ "sys.stdout.write(sys.argv[1])\n");
+ std::string abc("abcdefghijklmnopqrstuvwxyz");
+ py.mParams.args.add(abc);
+ py.mParams.files.add(LLProcess::FileParam()); // stdin
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
+ py.launch();
+ LLProcess::ReadPipe& childout(py.mPy->getReadPipe(LLProcess::STDOUT));
+ // listen for incoming data on childout
+ EventListener listener(childout.getPump());
+ // but set limit
+ childout.setLimit(10);
+ ensure_equals("getLimit() after setlimit(10)", childout.getLimit(), 10);
+ // okay, pump I/O to pick up output from child
+ waitfor(*py.mPy);
+ ensure("no events", ! listener.mHistory.empty());
+ // For all we know, that data could have arrived in several different
+ // bursts... probably not, but anyway, only check the last one.
+ ensure_equals("event[\"len\"]",
+ listener.mHistory.back()["len"].asInteger(), abc.length());
+ ensure_equals("length of setLimit(10) data",
+ listener.mHistory.back()["data"].asString().length(), 10);
+ }
+
+ template<> template<>
+ void object::test<19>()
+ {
+ set_test_name("peek() ReadPipe data");
+ PythonProcessLauncher py("peek() ReadPipe",
+ "import sys\n"
+ "sys.stdout.write(sys.argv[1])\n");
+ std::string abc("abcdefghijklmnopqrstuvwxyz");
+ py.mParams.args.add(abc);
+ py.mParams.files.add(LLProcess::FileParam()); // stdin
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
+ py.launch();
+ LLProcess::ReadPipe& childout(py.mPy->getReadPipe(LLProcess::STDOUT));
+ // okay, pump I/O to pick up output from child
+ waitfor(*py.mPy);
+ // peek() with substr args
+ ensure_equals("peek()", childout.peek(), abc);
+ ensure_equals("peek(23)", childout.peek(23), abc.substr(23));
+ ensure_equals("peek(5, 3)", childout.peek(5, 3), abc.substr(5, 3));
+ ensure_equals("peek(27, 2)", childout.peek(27, 2), "");
+ ensure_equals("peek(23, 5)", childout.peek(23, 5), "xyz");
+ // contains() -- we don't exercise as thoroughly as find() because the
+ // contains() implementation is trivially (and visibly) based on find()
+ ensure("contains(\":\")", ! childout.contains(":"));
+ ensure("contains(':')", ! childout.contains(':'));
+ ensure("contains(\"d\")", childout.contains("d"));
+ ensure("contains('d')", childout.contains('d'));
+ ensure("contains(\"klm\")", childout.contains("klm"));
+ ensure("contains(\"klx\")", ! childout.contains("klx"));
+ // find()
+ ensure("find(\":\")", childout.find(":") == LLProcess::ReadPipe::npos);
+ ensure("find(':')", childout.find(':') == LLProcess::ReadPipe::npos);
+ ensure_equals("find(\"d\")", childout.find("d"), 3);
+ ensure_equals("find('d')", childout.find('d'), 3);
+ ensure_equals("find(\"d\", 3)", childout.find("d", 3), 3);
+ ensure_equals("find('d', 3)", childout.find('d', 3), 3);
+ ensure("find(\"d\", 4)", childout.find("d", 4) == LLProcess::ReadPipe::npos);
+ ensure("find('d', 4)", childout.find('d', 4) == LLProcess::ReadPipe::npos);
+ // The case of offset == end and offset > end are different. In the
+ // first case, we can form a valid (albeit empty) iterator range and
+ // search that. In the second, guard logic in the implementation must
+ // realize we can't form a valid iterator range.
+ ensure("find(\"d\", 26)", childout.find("d", 26) == LLProcess::ReadPipe::npos);
+ ensure("find('d', 26)", childout.find('d', 26) == LLProcess::ReadPipe::npos);
+ ensure("find(\"d\", 27)", childout.find("d", 27) == LLProcess::ReadPipe::npos);
+ ensure("find('d', 27)", childout.find('d', 27) == LLProcess::ReadPipe::npos);
+ ensure_equals("find(\"ghi\")", childout.find("ghi"), 6);
+ ensure_equals("find(\"ghi\", 6)", childout.find("ghi"), 6);
+ ensure("find(\"ghi\", 7)", childout.find("ghi", 7) == LLProcess::ReadPipe::npos);
+ ensure("find(\"ghi\", 26)", childout.find("ghi", 26) == LLProcess::ReadPipe::npos);
+ ensure("find(\"ghi\", 27)", childout.find("ghi", 27) == LLProcess::ReadPipe::npos);
+ }
+
+ template<> template<>
+ void object::test<20>()
+ {
+ set_test_name("good postend");
+ PythonProcessLauncher py("postend",
+ "import sys\n"
+ "sys.exit(35)\n");
+ std::string pumpname("postend");
+ EventListener listener(LLEventPumps::instance().obtain(pumpname));
+ py.mParams.postend = pumpname;
+ py.launch();
+ LLProcess::id childid(py.mPy->getProcessID());
+ // Don't use waitfor(), which calls isRunning(); instead wait for an
+ // event on pumpname.
+ int i, timeout = 60;
+ for (i = 0; i < timeout && listener.mHistory.empty(); ++i)
+ {
+ yield();
+ }
+ ensure("no postend event", i < timeout);
+ ensure_equals("number of postend events", listener.mHistory.size(), 1);
+ LLSD postend(listener.mHistory.front());
+ ensure_equals("id", postend["id"].asInteger(), childid);
+ ensure("desc empty", ! postend["desc"].asString().empty());
+ ensure_equals("state", postend["state"].asInteger(), LLProcess::EXITED);
+ ensure_equals("data", postend["data"].asInteger(), 35);
+ std::string str(postend["string"]);
+ ensure_contains("string", str, "exited");
+ ensure_contains("string", str, "35");
+ }
+
+ template<> template<>
+ void object::test<21>()
+ {
+ set_test_name("bad postend");
+ std::string pumpname("postend");
+ EventListener listener(LLEventPumps::instance().obtain(pumpname));
+ LLProcess::Params params;
+ params.desc = "bad postend";
+ params.postend = pumpname;
+ LLProcessPtr child = LLProcess::create(params);
+ ensure("shouldn't have launched", ! child);
+ ensure_equals("number of postend events", listener.mHistory.size(), 1);
+ LLSD postend(listener.mHistory.front());
+ ensure("has id", ! postend.has("id"));
+ ensure_equals("desc", postend["desc"].asString(), std::string(params.desc));
+ ensure_equals("state", postend["state"].asInteger(), LLProcess::UNSTARTED);
+ ensure("has data", ! postend.has("data"));
+ std::string error(postend["string"]);
+ // All we get from canned parameter validation is a bool, so the
+ // "validation failed" message we ourselves generate can't mention
+ // "executable" by name. Just check that it's nonempty.
+ //ensure_contains("error", error, "executable");
+ ensure("string", ! error.empty());
+ }
+
+ // TODO:
+ // test EOF -- check logging
+
+} // namespace tut
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index 72322c3b72..e625545763 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -40,41 +40,15 @@ typedef U32 uint32_t;
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
-#include "llprocesslauncher.h"
+#include "llprocess.h"
#endif
-#include <sstream>
-
-/*==========================================================================*|
-// Whoops, seems Linden's Boost package and the viewer are built with
-// different settings of VC's /Zc:wchar_t switch! Using Boost.Filesystem
-// pathname operations produces Windows link errors:
-// unresolved external symbol "private: static class std::codecvt<unsigned short,
-// char,int> const * & __cdecl boost::filesystem3::path::wchar_t_codecvt_facet()"
-// unresolved external symbol "void __cdecl boost::filesystem3::path_traits::convert()"
-// See:
-// http://boost.2283326.n4.nabble.com/filesystem-v3-unicode-and-std-codecvt-linker-error-td3455549.html
-// which points to:
-// http://msdn.microsoft.com/en-us/library/dh8che7s%28v=VS.100%29.aspx
-
-// As we're not trying to preserve compatibility with old Boost.Filesystem
-// code, but rather writing brand-new code, use the newest available
-// Filesystem API.
-#define BOOST_FILESYSTEM_VERSION 3
-#include "boost/filesystem.hpp"
-#include "boost/filesystem/v3/fstream.hpp"
-|*==========================================================================*/
#include "boost/range.hpp"
#include "boost/foreach.hpp"
#include "boost/function.hpp"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
namespace lambda = boost::lambda;
-/*==========================================================================*|
-// Aaaarrgh, Linden's Boost package doesn't even include Boost.Iostreams!
-#include "boost/iostreams/stream.hpp"
-#include "boost/iostreams/device/file_descriptor.hpp"
-|*==========================================================================*/
#include "../llsd.h"
#include "../llsdserialize.h"
@@ -82,236 +56,17 @@ namespace lambda = boost::lambda;
#include "../llformat.h"
#include "../test/lltut.h"
+#include "../test/manageapr.h"
+#include "../test/namedtempfile.h"
#include "stringize.h"
+static ManageAPR manager;
+
std::vector<U8> string_to_vector(const std::string& str)
{
return std::vector<U8>(str.begin(), str.end());
}
-#if ! LL_WINDOWS
-// We want to call strerror_r(), but alarmingly, there are two different
-// variants. The one that returns int always populates the passed buffer
-// (except in case of error), whereas the other one always returns a valid
-// char* but might or might not populate the passed buffer. How do we know
-// which one we're getting? Define adapters for each and let the compiler
-// select the applicable adapter.
-
-// strerror_r() returns char*
-std::string message_from(int /*orig_errno*/, const char* /*buffer*/, const char* strerror_ret)
-{
- return strerror_ret;
-}
-
-// strerror_r() returns int
-std::string message_from(int orig_errno, const char* buffer, int strerror_ret)
-{
- if (strerror_ret == 0)
- {
- return buffer;
- }
- // Here strerror_r() has set errno. Since strerror_r() has already failed,
- // seems like a poor bet to call it again to diagnose its own error...
- int stre_errno = errno;
- if (stre_errno == ERANGE)
- {
- return STRINGIZE("strerror_r() can't explain errno " << orig_errno
- << " (buffer too small)");
- }
- if (stre_errno == EINVAL)
- {
- return STRINGIZE("unknown errno " << orig_errno);
- }
- // Here we don't even understand the errno from strerror_r()!
- return STRINGIZE("strerror_r() can't explain errno " << orig_errno
- << " (error " << stre_errno << ')');
-}
-#endif // ! LL_WINDOWS
-
-// boost::filesystem::temp_directory_path() isn't yet in Boost 1.45! :-(
-std::string temp_directory_path()
-{
-#if LL_WINDOWS
- char buffer[4096];
- GetTempPathA(sizeof(buffer), buffer);
- return buffer;
-
-#else // LL_DARWIN, LL_LINUX
- static const char* vars[] = { "TMPDIR", "TMP", "TEMP", "TEMPDIR" };
- BOOST_FOREACH(const char* var, vars)
- {
- const char* found = getenv(var);
- if (found)
- return found;
- }
- return "/tmp";
-#endif // LL_DARWIN, LL_LINUX
-}
-
-// Windows presents a kinda sorta compatibility layer. Code to the yucky
-// Windows names because they're less likely than the Posix names to collide
-// with any other names in this source.
-#if LL_WINDOWS
-#define _remove DeleteFileA
-#else // ! LL_WINDOWS
-#define _open open
-#define _write write
-#define _close close
-#define _remove remove
-#endif // ! LL_WINDOWS
-
-// Create a text file with specified content "somewhere in the
-// filesystem," cleaning up when it goes out of scope.
-class NamedTempFile
-{
-public:
- // Function that accepts an ostream ref and (presumably) writes stuff to
- // it, e.g.:
- // (lambda::_1 << "the value is " << 17 << '\n')
- typedef boost::function<void(std::ostream&)> Streamer;
-
- NamedTempFile(const std::string& ext, const std::string& content):
- mPath(temp_directory_path())
- {
- createFile(ext, lambda::_1 << content);
- }
-
- // Disambiguate when passing string literal
- NamedTempFile(const std::string& ext, const char* content):
- mPath(temp_directory_path())
- {
- createFile(ext, lambda::_1 << content);
- }
-
- NamedTempFile(const std::string& ext, const Streamer& func):
- mPath(temp_directory_path())
- {
- createFile(ext, func);
- }
-
- ~NamedTempFile()
- {
- _remove(mPath.c_str());
- }
-
- std::string getName() const { return mPath; }
-
-private:
- void createFile(const std::string& ext, const Streamer& func)
- {
- // Silly maybe, but use 'ext' as the name prefix. Strip off a leading
- // '.' if present.
- int pfx_offset = ((! ext.empty()) && ext[0] == '.')? 1 : 0;
-
-#if ! LL_WINDOWS
- // Make sure mPath ends with a directory separator, if it doesn't already.
- if (mPath.empty() ||
- ! (mPath[mPath.length() - 1] == '\\' || mPath[mPath.length() - 1] == '/'))
- {
- mPath.append("/");
- }
-
- // mkstemp() accepts and modifies a char* template string. Generate
- // the template string, then copy to modifiable storage.
- // mkstemp() requires its template string to end in six X's.
- mPath += ext.substr(pfx_offset) + "XXXXXX";
- // Copy to vector<char>
- std::vector<char> pathtemplate(mPath.begin(), mPath.end());
- // append a nul byte for classic-C semantics
- pathtemplate.push_back('\0');
- // std::vector promises that a pointer to the 0th element is the same
- // as a pointer to a contiguous classic-C array
- int fd(mkstemp(&pathtemplate[0]));
- if (fd == -1)
- {
- // The documented errno values (http://linux.die.net/man/3/mkstemp)
- // are used in a somewhat unusual way, so provide context-specific
- // errors.
- if (errno == EEXIST)
- {
- LL_ERRS("NamedTempFile") << "mkstemp(\"" << mPath
- << "\") could not create unique file " << LL_ENDL;
- }
- if (errno == EINVAL)
- {
- LL_ERRS("NamedTempFile") << "bad mkstemp() file path template '"
- << mPath << "'" << LL_ENDL;
- }
- // Shrug, something else
- int mkst_errno = errno;
- char buffer[256];
- LL_ERRS("NamedTempFile") << "mkstemp(\"" << mPath << "\") failed: "
- << message_from(mkst_errno, buffer,
- strerror_r(mkst_errno, buffer, sizeof(buffer)))
- << LL_ENDL;
- }
- // mkstemp() seems to have worked! Capture the modified filename.
- // Avoid the nul byte we appended.
- mPath.assign(pathtemplate.begin(), (pathtemplate.end()-1));
-
-/*==========================================================================*|
- // Define an ostream on the open fd. Tell it to close fd on destruction.
- boost::iostreams::stream<boost::iostreams::file_descriptor_sink>
- out(fd, boost::iostreams::close_handle);
-|*==========================================================================*/
-
- // Write desired content.
- std::ostringstream out;
- // Stream stuff to it.
- func(out);
-
- std::string data(out.str());
- int written(_write(fd, data.c_str(), data.length()));
- int closed(_close(fd));
- llassert_always(written == data.length() && closed == 0);
-
-#else // LL_WINDOWS
- // GetTempFileName() is documented to require a MAX_PATH buffer.
- char tempname[MAX_PATH];
- // Use 'ext' as filename prefix, but skip leading '.' if any.
- // The 0 param is very important: requests iterating until we get a
- // unique name.
- if (0 == GetTempFileNameA(mPath.c_str(), ext.c_str() + pfx_offset, 0, tempname))
- {
- // I always have to look up this call... :-P
- LPSTR msgptr;
- FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- LPSTR(&msgptr), // have to cast (char**) to (char*)
- 0, NULL );
- LL_ERRS("NamedTempFile") << "GetTempFileName(\"" << mPath << "\", \""
- << (ext.c_str() + pfx_offset) << "\") failed: "
- << msgptr << LL_ENDL;
- LocalFree(msgptr);
- }
- // GetTempFileName() appears to have worked! Capture the actual
- // filename.
- mPath = tempname;
- // Open the file and stream content to it. Destructor will close.
- std::ofstream out(tempname);
- func(out);
-
-#endif // LL_WINDOWS
- }
-
- void peep()
- {
- std::cout << "File '" << mPath << "' contains:\n";
- std::ifstream reader(mPath.c_str());
- std::string line;
- while (std::getline(reader, line))
- std::cout << line << '\n';
- std::cout << "---\n";
- }
-
- std::string mPath;
-};
-
namespace tut
{
struct sd_xml_data
@@ -1783,7 +1538,7 @@ namespace tut
const char* PYTHON(getenv("PYTHON"));
ensure("Set $PYTHON to the Python interpreter", PYTHON);
- NamedTempFile scriptfile(".py", script);
+ NamedTempFile scriptfile("py", script);
#if LL_WINDOWS
std::string q("\"");
@@ -1802,14 +1557,15 @@ namespace tut
}
#else // LL_DARWIN, LL_LINUX
- LLProcessLauncher py;
- py.setExecutable(PYTHON);
- py.addArgument(scriptfile.getName());
- ensure_equals(STRINGIZE("Couldn't launch " << desc << " script"), py.launch(), 0);
+ LLProcess::Params params;
+ params.executable = PYTHON;
+ params.args.add(scriptfile.getName());
+ LLProcessPtr py(LLProcess::create(params));
+ ensure(STRINGIZE("Couldn't launch " << desc << " script"), py);
// Implementing timeout would mean messing with alarm() and
// catching SIGALRM... later maybe...
int status(0);
- if (waitpid(py.getProcessID(), &status, 0) == -1)
+ if (waitpid(py->getProcessID(), &status, 0) == -1)
{
int waitpid_errno(errno);
ensure_equals(STRINGIZE("Couldn't retrieve rc from " << desc << " script: "
@@ -1888,12 +1644,12 @@ namespace tut
" else:\n"
" assert False, 'Too many data items'\n";
- // Create a something.llsd file containing 'data' serialized to
+ // Create an llsdXXXXXX file containing 'data' serialized to
// notation. It's important to separate with newlines because Python's
// llsd module doesn't support parsing from a file stream, only from a
// string, so we have to know how much of the file to read into a
// string.
- NamedTempFile file(".llsd",
+ NamedTempFile file("llsd",
// NamedTempFile's boost::function constructor
// takes a callable. To this callable it passes the
// std::ostream with which it's writing the
@@ -1926,7 +1682,7 @@ namespace tut
// Create an empty data file. This is just a placeholder for our
// script to write into. Create it to establish a unique name that
// we know.
- NamedTempFile file(".llsd", "");
+ NamedTempFile file("llsd", "");
python("write Python notation",
lambda::_1 <<
diff --git a/indra/llcommon/tests/llstreamqueue_test.cpp b/indra/llcommon/tests/llstreamqueue_test.cpp
new file mode 100644
index 0000000000..050ad5c5bf
--- /dev/null
+++ b/indra/llcommon/tests/llstreamqueue_test.cpp
@@ -0,0 +1,197 @@
+/**
+ * @file llstreamqueue_test.cpp
+ * @author Nat Goodspeed
+ * @date 2012-01-05
+ * @brief Test for llstreamqueue.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llstreamqueue.h"
+// STL headers
+#include <vector>
+// std headers
+// external library headers
+#include <boost/foreach.hpp>
+// other Linden headers
+#include "../test/lltut.h"
+#include "stringize.h"
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct llstreamqueue_data
+ {
+ llstreamqueue_data():
+ // we want a buffer with actual bytes in it, not an empty vector
+ buffer(10)
+ {}
+ // As LLStreamQueue is merely a typedef for
+ // LLGenericStreamQueue<char>, and no logic in LLGenericStreamQueue is
+ // specific to the <char> instantiation, we're comfortable for now
+ // testing only the narrow-char version.
+ LLStreamQueue strq;
+ // buffer for use in multiple tests
+ std::vector<char> buffer;
+ };
+ typedef test_group<llstreamqueue_data> llstreamqueue_group;
+ typedef llstreamqueue_group::object object;
+ llstreamqueue_group llstreamqueuegrp("llstreamqueue");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("empty LLStreamQueue");
+ ensure_equals("brand-new LLStreamQueue isn't empty",
+ strq.size(), 0);
+ ensure_equals("brand-new LLStreamQueue returns data",
+ strq.asSource().read(&buffer[0], buffer.size()), 0);
+ strq.asSink().close();
+ ensure_equals("closed empty LLStreamQueue not at EOF",
+ strq.asSource().read(&buffer[0], buffer.size()), -1);
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ set_test_name("one internal block, one buffer");
+ LLStreamQueue::Sink sink(strq.asSink());
+ ensure_equals("write(\"\")", sink.write("", 0), 0);
+ ensure_equals("0 write should leave LLStreamQueue empty (size())",
+ strq.size(), 0);
+ ensure_equals("0 write should leave LLStreamQueue empty (peek())",
+ strq.peek(&buffer[0], buffer.size()), 0);
+ // The meaning of "atomic" is that it must be smaller than our buffer.
+ std::string atomic("atomic");
+ ensure("test data exceeds buffer", atomic.length() < buffer.size());
+ ensure_equals(STRINGIZE("write(\"" << atomic << "\")"),
+ sink.write(&atomic[0], atomic.length()), atomic.length());
+ ensure_equals("size() after write()", strq.size(), atomic.length());
+ size_t peeklen(strq.peek(&buffer[0], buffer.size()));
+ ensure_equals(STRINGIZE("peek(\"" << atomic << "\")"),
+ peeklen, atomic.length());
+ ensure_equals(STRINGIZE("peek(\"" << atomic << "\") result"),
+ std::string(buffer.begin(), buffer.begin() + peeklen), atomic);
+ ensure_equals("size() after peek()", strq.size(), atomic.length());
+ // peek() should not consume. Use a different buffer to prove it isn't
+ // just leftover data from the first peek().
+ std::vector<char> again(buffer.size());
+ peeklen = size_t(strq.peek(&again[0], again.size()));
+ ensure_equals(STRINGIZE("peek(\"" << atomic << "\") again"),
+ peeklen, atomic.length());
+ ensure_equals(STRINGIZE("peek(\"" << atomic << "\") again result"),
+ std::string(again.begin(), again.begin() + peeklen), atomic);
+ // now consume.
+ std::vector<char> third(buffer.size());
+ size_t readlen(strq.read(&third[0], third.size()));
+ ensure_equals(STRINGIZE("read(\"" << atomic << "\")"),
+ readlen, atomic.length());
+ ensure_equals(STRINGIZE("read(\"" << atomic << "\") result"),
+ std::string(third.begin(), third.begin() + readlen), atomic);
+ ensure_equals("peek() after read()", strq.peek(&buffer[0], buffer.size()), 0);
+ ensure_equals("size() after read()", strq.size(), 0);
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ set_test_name("basic skip()");
+ std::string lovecraft("lovecraft");
+ ensure("test data exceeds buffer", lovecraft.length() < buffer.size());
+ ensure_equals(STRINGIZE("write(\"" << lovecraft << "\")"),
+ strq.write(&lovecraft[0], lovecraft.length()), lovecraft.length());
+ size_t peeklen(strq.peek(&buffer[0], buffer.size()));
+ ensure_equals(STRINGIZE("peek(\"" << lovecraft << "\")"),
+ peeklen, lovecraft.length());
+ ensure_equals(STRINGIZE("peek(\"" << lovecraft << "\") result"),
+ std::string(buffer.begin(), buffer.begin() + peeklen), lovecraft);
+ std::streamsize skip1(4);
+ ensure_equals(STRINGIZE("skip(" << skip1 << ")"), strq.skip(skip1), skip1);
+ ensure_equals("size() after skip()", strq.size(), lovecraft.length() - skip1);
+ size_t readlen(strq.read(&buffer[0], buffer.size()));
+ ensure_equals(STRINGIZE("read(\"" << lovecraft.substr(skip1) << "\")"),
+ readlen, lovecraft.length() - skip1);
+ ensure_equals(STRINGIZE("read(\"" << lovecraft.substr(skip1) << "\") result"),
+ std::string(buffer.begin(), buffer.begin() + readlen),
+ lovecraft.substr(skip1));
+ ensure_equals("unconsumed", strq.read(&buffer[0], buffer.size()), 0);
+ }
+
+ template<> template<>
+ void object::test<4>()
+ {
+ set_test_name("skip() multiple blocks");
+ std::string blocks[] = { "books of ", "H.P. ", "Lovecraft" };
+ std::streamsize total(blocks[0].length() + blocks[1].length() + blocks[2].length());
+ std::streamsize leave(5); // len("craft") above
+ std::streamsize skip(total - leave);
+ std::streamsize written(0);
+ BOOST_FOREACH(const std::string& block, blocks)
+ {
+ written += strq.write(&block[0], block.length());
+ ensure_equals("size() after write()", strq.size(), written);
+ }
+ std::streamsize skiplen(strq.skip(skip));
+ ensure_equals(STRINGIZE("skip(" << skip << ")"), skiplen, skip);
+ ensure_equals("size() after skip()", strq.size(), leave);
+ size_t readlen(strq.read(&buffer[0], buffer.size()));
+ ensure_equals("read(\"craft\")", readlen, leave);
+ ensure_equals("read(\"craft\") result",
+ std::string(buffer.begin(), buffer.begin() + readlen), "craft");
+ }
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("concatenate blocks");
+ std::string blocks[] = { "abcd", "efghij", "klmnopqrs" };
+ BOOST_FOREACH(const std::string& block, blocks)
+ {
+ strq.write(&block[0], block.length());
+ }
+ std::vector<char> longbuffer(30);
+ std::streamsize readlen(strq.read(&longbuffer[0], longbuffer.size()));
+ ensure_equals("read() multiple blocks",
+ readlen, blocks[0].length() + blocks[1].length() + blocks[2].length());
+ ensure_equals("read() multiple blocks result",
+ std::string(longbuffer.begin(), longbuffer.begin() + readlen),
+ blocks[0] + blocks[1] + blocks[2]);
+ }
+
+ template<> template<>
+ void object::test<6>()
+ {
+ set_test_name("split blocks");
+ std::string blocks[] = { "abcdefghijklm", "nopqrstuvwxyz" };
+ BOOST_FOREACH(const std::string& block, blocks)
+ {
+ strq.write(&block[0], block.length());
+ }
+ strq.close();
+ // We've already verified what strq.size() should be at this point;
+ // see above test named "skip() multiple blocks"
+ std::streamsize chksize(strq.size());
+ std::streamsize readlen(strq.read(&buffer[0], buffer.size()));
+ ensure_equals("read() 0", readlen, buffer.size());
+ ensure_equals("read() 0 result", std::string(buffer.begin(), buffer.end()), "abcdefghij");
+ chksize -= readlen;
+ ensure_equals("size() after read() 0", strq.size(), chksize);
+ readlen = strq.read(&buffer[0], buffer.size());
+ ensure_equals("read() 1", readlen, buffer.size());
+ ensure_equals("read() 1 result", std::string(buffer.begin(), buffer.end()), "klmnopqrst");
+ chksize -= readlen;
+ ensure_equals("size() after read() 1", strq.size(), chksize);
+ readlen = strq.read(&buffer[0], buffer.size());
+ ensure_equals("read() 2", readlen, chksize);
+ ensure_equals("read() 2 result",
+ std::string(buffer.begin(), buffer.begin() + readlen), "uvwxyz");
+ ensure_equals("read() 3", strq.read(&buffer[0], buffer.size()), -1);
+ }
+} // namespace tut
diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp
index 6a1cbf652a..93d3968dbf 100644
--- a/indra/llcommon/tests/llstring_test.cpp
+++ b/indra/llcommon/tests/llstring_test.cpp
@@ -29,7 +29,11 @@
#include "linden_common.h"
#include "../test/lltut.h"
+#include <boost/assign/list_of.hpp>
#include "../llstring.h"
+#include "StringVec.h"
+
+using boost::assign::list_of;
namespace tut
{
@@ -750,4 +754,118 @@ namespace tut
ensure("empty substr.", !LLStringUtil::endsWith(empty, value));
ensure("empty everything.", !LLStringUtil::endsWith(empty, empty));
}
+
+ template<> template<>
+ void string_index_object_t::test<41>()
+ {
+ set_test_name("getTokens(\"delims\")");
+ ensure_equals("empty string", LLStringUtil::getTokens("", " "), StringVec());
+ ensure_equals("only delims",
+ LLStringUtil::getTokens(" \r\n ", " \r\n"), StringVec());
+ ensure_equals("sequence of delims",
+ LLStringUtil::getTokens(",,, one ,,,", ","), list_of("one"));
+ // nat considers this a dubious implementation side effect, but I'd
+ // hate to change it now...
+ ensure_equals("noncontiguous tokens",
+ LLStringUtil::getTokens(", ,, , one ,,,", ","), list_of("")("")("one"));
+ ensure_equals("space-padded tokens",
+ LLStringUtil::getTokens(", one , two ,", ","), list_of("one")("two"));
+ ensure_equals("no delims", LLStringUtil::getTokens("one", ","), list_of("one"));
+ }
+
+ // Shorthand for verifying that getTokens() behaves the same when you
+ // don't pass a string of escape characters, when you pass an empty string
+ // (different overloads), and when you pass a string of characters that
+ // aren't actually present.
+ void ensure_getTokens(const std::string& desc,
+ const std::string& string,
+ const std::string& drop_delims,
+ const std::string& keep_delims,
+ const std::string& quotes,
+ const std::vector<std::string>& expect)
+ {
+ ensure_equals(desc + " - no esc",
+ LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes),
+ expect);
+ ensure_equals(desc + " - empty esc",
+ LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes, ""),
+ expect);
+ ensure_equals(desc + " - unused esc",
+ LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes, "!"),
+ expect);
+ }
+
+ void ensure_getTokens(const std::string& desc,
+ const std::string& string,
+ const std::string& drop_delims,
+ const std::string& keep_delims,
+ const std::vector<std::string>& expect)
+ {
+ ensure_getTokens(desc, string, drop_delims, keep_delims, "", expect);
+ }
+
+ template<> template<>
+ void string_index_object_t::test<42>()
+ {
+ set_test_name("getTokens(\"delims\", etc.)");
+ // Signatures to test in this method:
+ // getTokens(string, drop_delims, keep_delims [, quotes [, escapes]])
+ // If you omit keep_delims, you get the older function (test above).
+
+ // cases like the getTokens(string, delims) tests above
+ ensure_getTokens("empty string", "", " ", "", StringVec());
+ ensure_getTokens("only delims",
+ " \r\n ", " \r\n", "", StringVec());
+ ensure_getTokens("sequence of delims",
+ ",,, one ,,,", ", ", "", list_of("one"));
+ // Note contrast with the case in the previous method
+ ensure_getTokens("noncontiguous tokens",
+ ", ,, , one ,,,", ", ", "", list_of("one"));
+ ensure_getTokens("space-padded tokens",
+ ", one , two ,", ", ", "",
+ list_of("one")("two"));
+ ensure_getTokens("no delims", "one", ",", "", list_of("one"));
+
+ // drop_delims vs. keep_delims
+ ensure_getTokens("arithmetic",
+ " ab+def / xx* yy ", " ", "+-*/",
+ list_of("ab")("+")("def")("/")("xx")("*")("yy"));
+
+ // quotes
+ ensure_getTokens("no quotes",
+ "She said, \"Don't go.\"", " ", ",", "",
+ list_of("She")("said")(",")("\"Don't")("go.\""));
+ ensure_getTokens("quotes",
+ "She said, \"Don't go.\"", " ", ",", "\"",
+ list_of("She")("said")(",")("Don't go."));
+ ensure_getTokens("quotes and delims",
+ "run c:/'Documents and Settings'/someone", " ", "", "'",
+ list_of("run")("c:/Documents and Settings/someone"));
+ ensure_getTokens("unmatched quote",
+ "baby don't leave", " ", "", "'",
+ list_of("baby")("don't")("leave"));
+ ensure_getTokens("adjacent quoted",
+ "abc'def \"ghi'\"jkl' mno\"pqr", " ", "", "\"'",
+ list_of("abcdef \"ghijkl' mnopqr"));
+ ensure_getTokens("quoted empty string",
+ "--set SomeVar ''", " ", "", "'",
+ list_of("--set")("SomeVar")(""));
+
+ // escapes
+ // Don't use backslash as an escape for these tests -- you'll go nuts
+ // between the C++ string scanner and getTokens() escapes. Test with
+ // something else!
+ ensure_equals("escaped delims",
+ LLStringUtil::getTokens("^ a - dog^-gone^ phrase", " ", "-", "", "^"),
+ list_of(" a")("-")("dog-gone phrase"));
+ ensure_equals("escaped quotes",
+ LLStringUtil::getTokens("say: 'this isn^'t w^orking'.", " ", "", "'", "^"),
+ list_of("say:")("this isn't working."));
+ ensure_equals("escaped escape",
+ LLStringUtil::getTokens("want x^^2", " ", "", "", "^"),
+ list_of("want")("x^2"));
+ ensure_equals("escape at end",
+ LLStringUtil::getTokens("it's^ up there^", " ", "", "'", "^"),
+ list_of("it's up")("there^"));
+ }
}
diff --git a/indra/llcommon/tests/setpython.py b/indra/llcommon/tests/setpython.py
deleted file mode 100644
index df7b90428e..0000000000
--- a/indra/llcommon/tests/setpython.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/python
-"""\
-@file setpython.py
-@author Nat Goodspeed
-@date 2011-07-13
-@brief Set PYTHON environment variable for tests that care.
-
-$LicenseInfo:firstyear=2011&license=viewerlgpl$
-Copyright (c) 2011, Linden Research, Inc.
-$/LicenseInfo$
-"""
-
-import os
-import sys
-import subprocess
-
-if __name__ == "__main__":
- os.environ["PYTHON"] = sys.executable
- sys.exit(subprocess.call(sys.argv[1:]))
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 28dc3bd313..ad2eb0f69c 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -46,7 +46,7 @@ LLImageDecodeThread::~LLImageDecodeThread()
// MAIN THREAD
// virtual
-S32 LLImageDecodeThread::update(U32 max_time_ms)
+S32 LLImageDecodeThread::update(F32 max_time_ms)
{
LLMutexLock lock(mCreationMutex);
for (creation_list_t::iterator iter = mCreationList.begin();
diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h
index c684222fa5..1bfb0ddfd3 100644
--- a/indra/llimage/llimageworker.h
+++ b/indra/llimage/llimageworker.h
@@ -78,7 +78,7 @@ public:
handle_t decodeImage(LLImageFormatted* image,
U32 priority, S32 discard, BOOL needs_aux,
Responder* responder);
- S32 update(U32 max_time_ms);
+ S32 update(F32 max_time_ms);
// Used by unit tests to check the consistency of the thread instance
S32 tut_size();
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index 3c1ae45d68..1b11e83b4a 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -80,8 +80,8 @@ public:
typedef LLOctreeTraveler<T> oct_traveler;
typedef LLTreeTraveler<T> tree_traveler;
typedef typename std::set<LLPointer<T> > element_list;
- typedef typename std::set<LLPointer<T> >::iterator element_iter;
- typedef typename std::set<LLPointer<T> >::const_iterator const_element_iter;
+ typedef typename element_list::iterator element_iter;
+ typedef typename element_list::const_iterator const_element_iter;
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
typedef typename std::vector<LLOctreeNode<T>* > child_list;
typedef LLTreeNode<T> BaseType;
@@ -114,6 +114,8 @@ public:
mOctant = ((oct_node*) mParent)->getOctant(mCenter);
}
+ mElementCount = 0;
+
clearChildren();
}
@@ -219,11 +221,11 @@ public:
void accept(oct_traveler* visitor) { visitor->visit(this); }
virtual bool isLeaf() const { return mChild.empty(); }
- U32 getElementCount() const { return mData.size(); }
+ U32 getElementCount() const { return mElementCount; }
element_list& getData() { return mData; }
const element_list& getData() const { return mData; }
- U32 getChildCount() const { return mChild.size(); }
+ U32 getChildCount() const { return mChildCount; }
oct_node* getChild(U32 index) { return mChild[index]; }
const oct_node* getChild(U32 index) const { return mChild[index]; }
child_list& getChildren() { return mChild; }
@@ -300,17 +302,13 @@ public:
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
-#if LL_OCTREE_PARANOIA_CHECK
//if this is a redundant insertion, error out (should never happen)
- if (mData.find(data) != mData.end())
- {
- llwarns << "Redundant octree insertion detected. " << data << llendl;
- return false;
- }
-#endif
+ llassert(mData.find(data) == mData.end());
mData.insert(data);
BaseType::insert(data);
+
+ mElementCount = mData.size();
return true;
}
else
@@ -346,6 +344,8 @@ public:
{
mData.insert(data);
BaseType::insert(data);
+
+ mElementCount = mData.size();
return true;
}
@@ -399,6 +399,7 @@ public:
if (mData.find(data) != mData.end())
{ //we have data
mData.erase(data);
+ mElementCount = mData.size();
notifyRemoval(data);
checkAlive();
return true;
@@ -436,6 +437,7 @@ public:
if (mData.find(data) != mData.end())
{
mData.erase(data);
+ mElementCount = mData.size();
notifyRemoval(data);
llwarns << "FOUND!" << llendl;
checkAlive();
@@ -452,7 +454,7 @@ public:
void clearChildren()
{
mChild.clear();
-
+ mChildCount = 0;
U32* foo = (U32*) mChildMap;
foo[0] = foo[1] = 0xFFFFFFFF;
}
@@ -512,9 +514,10 @@ public:
}
#endif
- mChildMap[child->getOctant()] = (U8) mChild.size();
+ mChildMap[child->getOctant()] = mChildCount;
mChild.push_back(child);
+ ++mChildCount;
child->setParent(this);
if (!silent)
@@ -534,21 +537,20 @@ public:
oct_listener* listener = getOctListener(i);
listener->handleChildRemoval(this, getChild(index));
}
-
-
if (destroy)
{
mChild[index]->destroy();
delete mChild[index];
}
mChild.erase(mChild.begin() + index);
+ --mChildCount;
//rebuild child map
U32* foo = (U32*) mChildMap;
foo[0] = foo[1] = 0xFFFFFFFF;
- for (U32 i = 0; i < mChild.size(); ++i)
+ for (U32 i = 0; i < mChildCount; ++i)
{
mChildMap[mChild[i]->getOctant()] = i;
}
@@ -601,8 +603,10 @@ protected:
child_list mChild;
U8 mChildMap[8];
+ U32 mChildCount;
element_list mData;
+ U32 mElementCount;
};
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index da0fa32963..761fc171c4 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2078,6 +2078,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
mFaceMask = 0x0;
mDetail = detail;
mSculptLevel = -2;
+ mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims
mIsMeshAssetLoaded = FALSE;
mLODScaleBias.setVec(1,1,1);
mHullPoints = NULL;
@@ -3144,6 +3145,8 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
{
F32 area = sculptGetSurfaceArea();
+ mSurfaceArea = area;
+
const F32 SCULPT_MAX_AREA = 384.f;
if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA)
@@ -4617,18 +4620,83 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
genBinormals(i);
}
- if (!face.mOctree)
- {
- face.createOctree();
- }
-
- //LLVector4a* p = (LLVector4a*) face.mPositions;
+ if (isUnique())
+ { //don't bother with an octree for flexi volumes
+ U32 tri_count = face.mNumIndices/3;
+
+ for (U32 j = 0; j < tri_count; ++j)
+ {
+ U16 idx0 = face.mIndices[j*3+0];
+ U16 idx1 = face.mIndices[j*3+1];
+ U16 idx2 = face.mIndices[j*3+2];
+
+ const LLVector4a& v0 = face.mPositions[idx0];
+ const LLVector4a& v1 = face.mPositions[idx1];
+ const LLVector4a& v2 = face.mPositions[idx2];
+
+ F32 a,b,t;
- LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal);
- intersect.traverse(face.mOctree);
- if (intersect.mHitFace)
+ if (LLTriangleRayIntersect(v0, v1, v2,
+ start, dir, a, b, t))
+ {
+ if ((t >= 0.f) && // if hit is after start
+ (t <= 1.f) && // and before end
+ (t < closest_t)) // and this hit is closer
+ {
+ closest_t = t;
+ hit_face = i;
+
+ if (intersection != NULL)
+ {
+ LLVector4a intersect = dir;
+ intersect.mul(closest_t);
+ intersect.add(start);
+ intersection->set(intersect.getF32ptr());
+ }
+
+
+ if (tex_coord != NULL)
+ {
+ LLVector2* tc = (LLVector2*) face.mTexCoords;
+ *tex_coord = ((1.f - a - b) * tc[idx0] +
+ a * tc[idx1] +
+ b * tc[idx2]);
+
+ }
+
+ if (normal!= NULL)
+ {
+ LLVector4* norm = (LLVector4*) face.mNormals;
+
+ *normal = ((1.f - a - b) * LLVector3(norm[idx0]) +
+ a * LLVector3(norm[idx1]) +
+ b * LLVector3(norm[idx2]));
+ }
+
+ if (bi_normal != NULL)
+ {
+ LLVector4* binormal = (LLVector4*) face.mBinormals;
+ *bi_normal = ((1.f - a - b) * LLVector3(binormal[idx0]) +
+ a * LLVector3(binormal[idx1]) +
+ b * LLVector3(binormal[idx2]));
+ }
+ }
+ }
+ }
+ }
+ else
{
- hit_face = i;
+ if (!face.mOctree)
+ {
+ face.createOctree();
+ }
+
+ LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal);
+ intersect.traverse(face.mOctree);
+ if (intersect.mHitFace)
+ {
+ hit_face = i;
+ }
}
}
}
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index afd1ec5eed..76cf9de613 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -963,6 +963,7 @@ public:
S32 getNumFaces() const;
S32 getNumVolumeFaces() const { return mVolumeFaces.size(); }
F32 getDetail() const { return mDetail; }
+ F32 getSurfaceArea() const { return mSurfaceArea; }
const LLVolumeParams& getParams() const { return mParams; }
LLVolumeParams getCopyOfParams() const { return mParams; }
const LLProfile& getProfile() const { return *mProfilep; }
@@ -1065,6 +1066,7 @@ public:
BOOL mUnique;
F32 mDetail;
S32 mSculptLevel;
+ F32 mSurfaceArea; //unscaled surface area
BOOL mIsMeshAssetLoaded;
LLVolumeParams mParams;
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp
index 0316797f00..250cace6e9 100644
--- a/indra/llmessage/llbuffer.cpp
+++ b/indra/llmessage/llbuffer.cpp
@@ -32,6 +32,9 @@
#include "llmath.h"
#include "llmemtype.h"
#include "llstl.h"
+#include "llthread.h"
+
+#define ASSERT_LLBUFFERARRAY_MUTEX_LOCKED llassert(!mMutexp || mMutexp->isSelfLocked());
/**
* LLSegment
@@ -224,7 +227,8 @@ void LLHeapBuffer::allocate(S32 size)
* LLBufferArray
*/
LLBufferArray::LLBufferArray() :
- mNextBaseChannel(0)
+ mNextBaseChannel(0),
+ mMutexp(NULL)
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
}
@@ -233,6 +237,8 @@ LLBufferArray::~LLBufferArray()
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer());
+
+ delete mMutexp;
}
// static
@@ -243,14 +249,57 @@ LLChannelDescriptors LLBufferArray::makeChannelConsumer(
return rv;
}
+void LLBufferArray::lock()
+{
+ if(mMutexp)
+ {
+ mMutexp->lock() ;
+ }
+}
+
+void LLBufferArray::unlock()
+{
+ if(mMutexp)
+ {
+ mMutexp->unlock() ;
+ }
+}
+
+LLMutex* LLBufferArray::getMutex()
+{
+ return mMutexp ;
+}
+
+void LLBufferArray::setThreaded(bool threaded)
+{
+ if(threaded)
+ {
+ if(!mMutexp)
+ {
+ mMutexp = new LLMutex(NULL);
+ }
+ }
+ else
+ {
+ if(mMutexp)
+ {
+ delete mMutexp ;
+ mMutexp = NULL ;
+ }
+ }
+}
+
LLChannelDescriptors LLBufferArray::nextChannel()
{
LLChannelDescriptors rv(mNextBaseChannel++);
return rv;
}
+//mMutexp should be locked before calling this.
S32 LLBufferArray::capacity() const
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
+
S32 total = 0;
const_buffer_iterator_t iter = mBuffers.begin();
const_buffer_iterator_t end = mBuffers.end();
@@ -263,6 +312,8 @@ S32 LLBufferArray::capacity() const
bool LLBufferArray::append(S32 channel, const U8* src, S32 len)
{
+ LLMutexLock lock(mMutexp) ;
+
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
if(copyIntoBuffers(channel, src, len, segments))
@@ -273,8 +324,11 @@ bool LLBufferArray::append(S32 channel, const U8* src, S32 len)
return false;
}
+//mMutexp should be locked before calling this.
bool LLBufferArray::prepend(S32 channel, const U8* src, S32 len)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
+
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
if(copyIntoBuffers(channel, src, len, segments))
@@ -293,6 +347,8 @@ bool LLBufferArray::insertAfter(
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
+
+ LLMutexLock lock(mMutexp) ;
if(mSegments.end() != segment)
{
++segment;
@@ -305,8 +361,11 @@ bool LLBufferArray::insertAfter(
return false;
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
+
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
segment_iterator_t end = mSegments.end();
segment_iterator_t it = getSegment(address);
@@ -335,20 +394,26 @@ LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
return rv;
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::beginSegment()
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
return mSegments.begin();
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::endSegment()
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
return mSegments.end();
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
U8* address,
LLSegment& segment)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
segment_iterator_t rv = mSegments.begin();
segment_iterator_t end = mSegments.end();
@@ -395,8 +460,10 @@ LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
return rv;
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
segment_iterator_t end = mSegments.end();
if(!address)
{
@@ -414,9 +481,11 @@ LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address)
return end;
}
+//mMutexp should be locked before calling this.
LLBufferArray::const_segment_iterator_t LLBufferArray::getSegment(
U8* address) const
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
const_segment_iterator_t end = mSegments.end();
if(!address)
{
@@ -466,6 +535,8 @@ S32 LLBufferArray::countAfter(S32 channel, U8* start) const
S32 count = 0;
S32 offset = 0;
const_segment_iterator_t it;
+
+ LLMutexLock lock(mMutexp) ;
const_segment_iterator_t end = mSegments.end();
if(start)
{
@@ -517,6 +588,8 @@ U8* LLBufferArray::readAfter(
len = 0;
S32 bytes_to_copy = 0;
const_segment_iterator_t it;
+
+ LLMutexLock lock(mMutexp) ;
const_segment_iterator_t end = mSegments.end();
if(start)
{
@@ -568,6 +641,7 @@ U8* LLBufferArray::seek(
U8* start,
S32 delta) const
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
const_segment_iterator_t it;
const_segment_iterator_t end = mSegments.end();
@@ -709,9 +783,14 @@ U8* LLBufferArray::seek(
return rv;
}
+//test use only
bool LLBufferArray::takeContents(LLBufferArray& source)
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
+
+ LLMutexLock lock(mMutexp);
+ source.lock();
+
std::copy(
source.mBuffers.begin(),
source.mBuffers.end(),
@@ -723,13 +802,17 @@ bool LLBufferArray::takeContents(LLBufferArray& source)
std::back_insert_iterator<segment_list_t>(mSegments));
source.mSegments.clear();
source.mNextBaseChannel = 0;
+ source.unlock();
+
return true;
}
+//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
S32 channel,
S32 len)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
// start at the end of the buffers, because it is the most likely
// to have free space.
@@ -765,8 +848,10 @@ LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
return send;
}
+//mMutexp should be locked before calling this.
bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
// Find out which buffer contains the segment, and if it is found,
@@ -792,13 +877,14 @@ bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter)
return rv;
}
-
+//mMutexp should be locked before calling this.
bool LLBufferArray::copyIntoBuffers(
S32 channel,
const U8* src,
S32 len,
std::vector<LLSegment>& segments)
{
+ ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
if(!src || !len) return false;
S32 copied = 0;
diff --git a/indra/llmessage/llbuffer.h b/indra/llmessage/llbuffer.h
index 1c42b6fbc6..ccdb9fa7ee 100644
--- a/indra/llmessage/llbuffer.h
+++ b/indra/llmessage/llbuffer.h
@@ -39,6 +39,7 @@
#include <list>
#include <vector>
+class LLMutex;
/**
* @class LLChannelDescriptors
* @brief A way simple interface to accesss channels inside a buffer
@@ -564,6 +565,29 @@ public:
* @return Returns true on success.
*/
bool eraseSegment(const segment_iterator_t& iter);
+
+ /**
+ * @brief Lock the mutex if it exists
+ * This method locks mMutexp to make accessing LLBufferArray thread-safe
+ */
+ void lock();
+
+ /**
+ * @brief Unlock the mutex if it exists
+ */
+ void unlock();
+
+ /**
+ * @brief Return mMutexp
+ */
+ LLMutex* getMutex();
+
+ /**
+ * @brief Set LLBufferArray to be shared across threads or not
+ * This method is to create mMutexp if is threaded.
+ * @param threaded Indicates this LLBufferArray instance is shared across threads if true.
+ */
+ void setThreaded(bool threaded);
//@}
protected:
@@ -595,6 +619,7 @@ protected:
S32 mNextBaseChannel;
buffer_list_t mBuffers;
segment_list_t mSegments;
+ LLMutex* mMutexp;
};
#endif // LL_LLBUFFER_H
diff --git a/indra/llmessage/llbufferstream.cpp b/indra/llmessage/llbufferstream.cpp
index 6257983c43..8d8ad05ad5 100644
--- a/indra/llmessage/llbufferstream.cpp
+++ b/indra/llmessage/llbufferstream.cpp
@@ -31,6 +31,7 @@
#include "llbuffer.h"
#include "llmemtype.h"
+#include "llthread.h"
static const S32 DEFAULT_OUTPUT_SEGMENT_SIZE = 1024 * 4;
@@ -62,6 +63,7 @@ int LLBufferStreamBuf::underflow()
return EOF;
}
+ LLMutexLock lock(mBuffer->getMutex());
LLBufferArray::segment_iterator_t iter;
LLBufferArray::segment_iterator_t end = mBuffer->endSegment();
U8* last_pos = (U8*)gptr();
@@ -149,6 +151,7 @@ int LLBufferStreamBuf::overflow(int c)
// since we got here, we have a buffer, and we have a character to
// put on it.
LLBufferArray::segment_iterator_t it;
+ LLMutexLock lock(mBuffer->getMutex());
it = mBuffer->makeSegment(mChannels.out(), DEFAULT_OUTPUT_SEGMENT_SIZE);
if(it != mBuffer->endSegment())
{
@@ -210,6 +213,7 @@ int LLBufferStreamBuf::sync()
// *NOTE: I bet we could just --address if address is not NULL.
// Need to think about that.
+ LLMutexLock lock(mBuffer->getMutex());
address = mBuffer->seek(mChannels.out(), address, -1);
if(address)
{
@@ -273,6 +277,8 @@ streampos LLBufferStreamBuf::seekoff(
// NULL is fine
break;
}
+
+ LLMutexLock lock(mBuffer->getMutex());
address = mBuffer->seek(mChannels.in(), base_addr, off);
if(address)
{
@@ -304,6 +310,8 @@ streampos LLBufferStreamBuf::seekoff(
// NULL is fine
break;
}
+
+ LLMutexLock lock(mBuffer->getMutex());
address = mBuffer->seek(mChannels.out(), base_addr, off);
if(address)
{
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 7ca25d07fc..3bcaffc275 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -72,10 +72,9 @@
static const U32 EASY_HANDLE_POOL_SIZE = 5;
static const S32 MULTI_PERFORM_CALL_REPEAT = 5;
-static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds
+static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds per operation
static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
-static
// DEBUG //
S32 gCurlEasyCount = 0;
S32 gCurlMultiCount = 0;
@@ -87,6 +86,11 @@ std::vector<LLMutex*> LLCurl::sSSLMutex;
std::string LLCurl::sCAPath;
std::string LLCurl::sCAFile;
LLCurlThread* LLCurl::sCurlThread = NULL ;
+LLMutex* LLCurl::sHandleMutexp = NULL ;
+S32 LLCurl::sTotalHandles = 0 ;
+bool LLCurl::sNotQuitting = true;
+F32 LLCurl::sCurlRequestTimeOut = 120.f; //seonds
+S32 LLCurl::sMaxHandles = 256; //max number of handles, (multi handles and easy handles combined).
void check_curl_code(CURLcode code)
{
@@ -219,14 +223,20 @@ namespace boost
std::set<CURL*> LLCurl::Easy::sFreeHandles;
std::set<CURL*> LLCurl::Easy::sActiveHandles;
+LLMutex* LLCurl::Easy::sHandleMutexp = NULL ;
//static
CURL* LLCurl::Easy::allocEasyHandle()
{
+ llassert(LLCurl::getCurlThread()) ;
+
CURL* ret = NULL;
+
+ LLMutexLock lock(sHandleMutexp) ;
+
if (sFreeHandles.empty())
{
- ret = curl_easy_init();
+ ret = LLCurl::newEasyHandle();
}
else
{
@@ -246,15 +256,27 @@ CURL* LLCurl::Easy::allocEasyHandle()
//static
void LLCurl::Easy::releaseEasyHandle(CURL* handle)
{
+ static const S32 MAX_NUM_FREE_HANDLES = 32 ;
+
if (!handle)
{
- llerrs << "handle cannot be NULL!" << llendl;
+ return ; //handle allocation failed.
+ //llerrs << "handle cannot be NULL!" << llendl;
}
+ LLMutexLock lock(sHandleMutexp) ;
if (sActiveHandles.find(handle) != sActiveHandles.end())
{
sActiveHandles.erase(handle);
- sFreeHandles.insert(handle);
+
+ if(sFreeHandles.size() < MAX_NUM_FREE_HANDLES)
+ {
+ sFreeHandles.insert(handle);
+ }
+ else
+ {
+ LLCurl::deleteEasyHandle(handle) ;
+ }
}
else
{
@@ -297,6 +319,14 @@ LLCurl::Easy::~Easy()
--gCurlEasyCount;
curl_slist_free_all(mHeaders);
for_each(mStrings.begin(), mStrings.end(), DeletePointerArray());
+
+ if (mResponder && LLCurl::sNotQuitting) //aborted
+ {
+ std::string reason("Request timeout, aborted.") ;
+ mResponder->completedRaw(408, //HTTP_REQUEST_TIME_OUT, timeout, abort
+ reason, mChannels, mOutput);
+ }
+ mResponder = NULL;
}
void LLCurl::Easy::resetState()
@@ -469,6 +499,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
LLProxy::getInstance()->applyProxySettings(this);
mOutput.reset(new LLBufferArray);
+ mOutput->setThreaded(true);
setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback);
setopt(CURLOPT_WRITEDATA, (void*)this);
@@ -512,36 +543,56 @@ void LLCurl::Easy::prepRequest(const std::string& url,
}
////////////////////////////////////////////////////////////////////////////
-
-LLCurl::Multi::Multi()
+LLCurl::Multi::Multi(F32 idle_time_out)
: mQueued(0),
mErrorCount(0),
mState(STATE_READY),
mDead(FALSE),
mMutexp(NULL),
- mDeletionMutexp(NULL)
+ mDeletionMutexp(NULL),
+ mEasyMutexp(NULL)
{
- mCurlMultiHandle = curl_multi_init();
+ mCurlMultiHandle = LLCurl::newMultiHandle();
if (!mCurlMultiHandle)
{
llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;
- mCurlMultiHandle = curl_multi_init();
+ mCurlMultiHandle = LLCurl::newMultiHandle();
}
- llassert_always(mCurlMultiHandle);
-
- if(LLCurl::getCurlThread()->getThreaded())
+ //llassert_always(mCurlMultiHandle);
+
+ if(mCurlMultiHandle)
{
- mMutexp = new LLMutex(NULL) ;
- mDeletionMutexp = new LLMutex(NULL) ;
- }
- LLCurl::getCurlThread()->addMulti(this) ;
+ if(LLCurl::getCurlThread()->getThreaded())
+ {
+ mMutexp = new LLMutex(NULL) ;
+ mDeletionMutexp = new LLMutex(NULL) ;
+ mEasyMutexp = new LLMutex(NULL) ;
+ }
+ LLCurl::getCurlThread()->addMulti(this) ;
- ++gCurlMultiCount;
+ mIdleTimeOut = idle_time_out ;
+ if(mIdleTimeOut < LLCurl::sCurlRequestTimeOut)
+ {
+ mIdleTimeOut = LLCurl::sCurlRequestTimeOut ;
+ }
+
+ ++gCurlMultiCount;
+ }
}
LLCurl::Multi::~Multi()
{
+ cleanup() ;
+}
+
+void LLCurl::Multi::cleanup()
+{
+ if(!mCurlMultiHandle)
+ {
+ return ; //nothing to clean.
+ }
+
// Clean up active
for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
iter != mEasyActiveList.end(); ++iter)
@@ -557,14 +608,22 @@ LLCurl::Multi::~Multi()
for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer());
mEasyFreeList.clear();
- check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle));
+ check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle));
+ mCurlMultiHandle = NULL ;
delete mMutexp ;
mMutexp = NULL ;
delete mDeletionMutexp ;
mDeletionMutexp = NULL ;
-
+ delete mEasyMutexp ;
+ mEasyMutexp = NULL ;
+
+ mQueued = 0 ;
+ mState = STATE_COMPLETED;
+
--gCurlMultiCount;
+
+ return ;
}
void LLCurl::Multi::lock()
@@ -585,39 +644,27 @@ void LLCurl::Multi::unlock()
void LLCurl::Multi::markDead()
{
- if(mDeletionMutexp)
- {
- mDeletionMutexp->lock() ;
- }
-
+ LLMutexLock lock(mDeletionMutexp) ;
+
mDead = TRUE ;
-
- if(mDeletionMutexp)
- {
- mDeletionMutexp->unlock() ;
- }
+ LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
}
void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
{
lock() ;
mState = state ;
+ unlock() ;
+
if(mState == STATE_READY)
{
LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_NORMAL) ;
- }
- unlock() ;
+ }
}
LLCurl::Multi::ePerformState LLCurl::Multi::getState()
{
- ePerformState state ;
-
- lock() ;
- state = mState ;
- unlock() ;
-
- return state ;
+ return mState;
}
bool LLCurl::Multi::isCompleted()
@@ -627,27 +674,30 @@ bool LLCurl::Multi::isCompleted()
bool LLCurl::Multi::waitToComplete()
{
+ if(!isValid())
+ {
+ return true ;
+ }
+
if(!mMutexp) //not threaded
{
doPerform() ;
return true ;
}
- bool completed ;
-
- lock() ;
- completed = (STATE_COMPLETED == mState) ;
+ bool completed = (STATE_COMPLETED == mState) ;
if(!completed)
{
- LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
+ LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_HIGH) ;
}
- unlock() ;
-
+
return completed;
}
CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue)
{
+ LLMutexLock lock(mMutexp) ;
+
CURLMsg* curlmsg = curl_multi_info_read(mCurlMultiHandle, msgs_in_queue);
return curlmsg;
}
@@ -655,10 +705,8 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue)
//return true if dead
bool LLCurl::Multi::doPerform()
{
- if(mDeletionMutexp)
- {
- mDeletionMutexp->lock() ;
- }
+ LLMutexLock lock(mDeletionMutexp) ;
+
bool dead = mDead ;
if(mDead)
@@ -675,6 +723,11 @@ bool LLCurl::Multi::doPerform()
call_count < MULTI_PERFORM_CALL_REPEAT;
call_count++)
{
+ LLMutexLock lock(mMutexp) ;
+
+ //WARNING: curl_multi_perform will block for many hundreds of milliseconds
+ // NEVER call this from the main thread, and NEVER allow the main thread to
+ // wait on a mutex held by this thread while curl_multi_perform is executing
CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
{
@@ -685,12 +738,12 @@ bool LLCurl::Multi::doPerform()
}
mQueued = q;
- setState(STATE_COMPLETED) ;
+ setState(STATE_COMPLETED) ;
+ mIdleTimer.reset() ;
}
-
- if(mDeletionMutexp)
+ else if(mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
{
- mDeletionMutexp->unlock() ;
+ dead = true ;
}
return dead ;
@@ -698,6 +751,11 @@ bool LLCurl::Multi::doPerform()
S32 LLCurl::Multi::process()
{
+ if(!isValid())
+ {
+ return 0 ;
+ }
+
waitToComplete() ;
if (getState() != STATE_COMPLETED)
@@ -715,10 +773,19 @@ S32 LLCurl::Multi::process()
if (msg->msg == CURLMSG_DONE)
{
U32 response = 0;
- easy_active_map_t::iterator iter = mEasyActiveMap.find(msg->easy_handle);
- if (iter != mEasyActiveMap.end())
+ Easy* easy = NULL ;
+
+ {
+ LLMutexLock lock(mEasyMutexp) ;
+ easy_active_map_t::iterator iter = mEasyActiveMap.find(msg->easy_handle);
+ if (iter != mEasyActiveMap.end())
+ {
+ easy = iter->second;
+ }
+ }
+
+ if(easy)
{
- Easy* easy = iter->second;
response = easy->report(msg->data.result);
removeEasy(easy);
}
@@ -743,19 +810,21 @@ S32 LLCurl::Multi::process()
LLCurl::Easy* LLCurl::Multi::allocEasy()
{
- Easy* easy = 0;
+ Easy* easy = 0;
if (mEasyFreeList.empty())
- {
+ {
easy = Easy::getEasy();
}
else
{
+ LLMutexLock lock(mEasyMutexp) ;
easy = *(mEasyFreeList.begin());
mEasyFreeList.erase(easy);
}
if (easy)
{
+ LLMutexLock lock(mEasyMutexp) ;
mEasyActiveList.insert(easy);
mEasyActiveMap[easy->getCurlHandle()] = easy;
}
@@ -764,6 +833,7 @@ LLCurl::Easy* LLCurl::Multi::allocEasy()
bool LLCurl::Multi::addEasy(Easy* easy)
{
+ LLMutexLock lock(mMutexp) ;
CURLMcode mcode = curl_multi_add_handle(mCurlMultiHandle, easy->getCurlHandle());
check_curl_multi_code(mcode);
//if (mcode != CURLM_OK)
@@ -776,22 +846,41 @@ bool LLCurl::Multi::addEasy(Easy* easy)
void LLCurl::Multi::easyFree(Easy* easy)
{
+ if(mEasyMutexp)
+ {
+ mEasyMutexp->lock() ;
+ }
+
mEasyActiveList.erase(easy);
mEasyActiveMap.erase(easy->getCurlHandle());
+
if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE)
- {
- easy->resetState();
+ {
mEasyFreeList.insert(easy);
+
+ if(mEasyMutexp)
+ {
+ mEasyMutexp->unlock() ;
+ }
+
+ easy->resetState();
}
else
{
+ if(mEasyMutexp)
+ {
+ mEasyMutexp->unlock() ;
+ }
delete easy;
}
}
void LLCurl::Multi::removeEasy(Easy* easy)
{
- check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
+ {
+ LLMutexLock lock(mMutexp) ;
+ check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
+ }
easyFree(easy);
}
@@ -819,7 +908,11 @@ bool LLCurlThread::CurlRequest::processRequest()
if(mMulti)
{
completed = mCurlThread->doMultiPerform(mMulti) ;
- setPriority(LLQueuedThread::PRIORITY_LOW) ;
+
+ if(!completed)
+ {
+ setPriority(LLQueuedThread::PRIORITY_LOW) ;
+ }
}
return completed ;
@@ -827,7 +920,15 @@ bool LLCurlThread::CurlRequest::processRequest()
void LLCurlThread::CurlRequest::finishRequest(bool completed)
{
- mCurlThread->deleteMulti(mMulti) ;
+ if(mMulti->isDead())
+ {
+ mCurlThread->deleteMulti(mMulti) ;
+ }
+ else
+ {
+ mCurlThread->cleanupMulti(mMulti) ; //being idle too long, remove the request.
+ }
+
mMulti = NULL ;
}
@@ -841,7 +942,7 @@ LLCurlThread::~LLCurlThread()
{
}
-S32 LLCurlThread::update(U32 max_time_ms)
+S32 LLCurlThread::update(F32 max_time_ms)
{
return LLQueuedThread::update(max_time_ms);
}
@@ -860,7 +961,19 @@ void LLCurlThread::addMulti(LLCurl::Multi* multi)
void LLCurlThread::killMulti(LLCurl::Multi* multi)
{
- multi->markDead() ;
+ if(!multi)
+ {
+ return ;
+ }
+
+ if(multi->isValid())
+ {
+ multi->markDead() ;
+ }
+ else
+ {
+ deleteMulti(multi) ;
+ }
}
//private
@@ -874,6 +987,13 @@ void LLCurlThread::deleteMulti(LLCurl::Multi* multi)
{
delete multi ;
}
+
+//private
+void LLCurlThread::cleanupMulti(LLCurl::Multi* multi)
+{
+ multi->cleanup() ;
+}
+
//------------------------------------------------------------
//static
@@ -906,7 +1026,14 @@ LLCurlRequest::~LLCurlRequest()
void LLCurlRequest::addMulti()
{
LLCurl::Multi* multi = new LLCurl::Multi();
-
+ if(!multi->isValid())
+ {
+ LLCurl::getCurlThread()->killMulti(multi) ;
+ mActiveMulti = NULL ;
+ mActiveRequestCount = 0 ;
+ return;
+ }
+
mMultiSet.insert(multi);
mActiveMulti = multi;
mActiveRequestCount = 0;
@@ -920,7 +1047,12 @@ LLCurl::Easy* LLCurlRequest::allocEasy()
{
addMulti();
}
- llassert_always(mActiveMulti);
+ if(!mActiveMulti)
+ {
+ return NULL ;
+ }
+
+ //llassert_always(mActiveMulti);
++mActiveRequestCount;
LLCurl::Easy* easy = mActiveMulti->allocEasy();
return easy;
@@ -1030,6 +1162,19 @@ S32 LLCurlRequest::process()
{
curlmulti_set_t::iterator curiter = iter++;
LLCurl::Multi* multi = *curiter;
+
+ if(!multi->isValid())
+ {
+ if(multi == mActiveMulti)
+ {
+ mActiveMulti = NULL ;
+ mActiveRequestCount = 0 ;
+ }
+ mMultiSet.erase(curiter) ;
+ LLCurl::getCurlThread()->killMulti(multi) ;
+ continue ;
+ }
+
S32 tres = multi->process();
res += tres;
if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
@@ -1050,6 +1195,19 @@ S32 LLCurlRequest::getQueued()
{
curlmulti_set_t::iterator curiter = iter++;
LLCurl::Multi* multi = *curiter;
+
+ if(!multi->isValid())
+ {
+ if(multi == mActiveMulti)
+ {
+ mActiveMulti = NULL ;
+ mActiveRequestCount = 0 ;
+ }
+ LLCurl::getCurlThread()->killMulti(multi);
+ mMultiSet.erase(curiter) ;
+ continue ;
+ }
+
queued += multi->mQueued;
if (multi->getState() != LLCurl::Multi::STATE_READY)
{
@@ -1069,13 +1227,22 @@ LLCurlEasyRequest::LLCurlEasyRequest()
{
mMulti = new LLCurl::Multi();
- mEasy = mMulti->allocEasy();
- if (mEasy)
+ if(mMulti->isValid())
{
- mEasy->setErrorBuffer();
- mEasy->setCA();
- // Set proxy settings if configured to do so.
- LLProxy::getInstance()->applyProxySettings(mEasy);
+ mEasy = mMulti->allocEasy();
+ if (mEasy)
+ {
+ mEasy->setErrorBuffer();
+ mEasy->setCA();
+ // Set proxy settings if configured to do so.
+ LLProxy::getInstance()->applyProxySettings(mEasy);
+ }
+ }
+ else
+ {
+ LLCurl::getCurlThread()->killMulti(mMulti) ;
+ mEasy = NULL ;
+ mMulti = NULL ;
}
}
@@ -1086,7 +1253,7 @@ LLCurlEasyRequest::~LLCurlEasyRequest()
void LLCurlEasyRequest::setopt(CURLoption option, S32 value)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(option, value);
}
@@ -1094,7 +1261,7 @@ void LLCurlEasyRequest::setopt(CURLoption option, S32 value)
void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setoptString(option, value);
}
@@ -1102,7 +1269,7 @@ void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value
void LLCurlEasyRequest::setPost(char* postdata, S32 size)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_POST, 1);
mEasy->setopt(CURLOPT_POSTFIELDS, postdata);
@@ -1112,7 +1279,7 @@ void LLCurlEasyRequest::setPost(char* postdata, S32 size)
void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* userdata)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_HEADERFUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_HEADERDATA, userdata); // aka CURLOPT_WRITEHEADER
@@ -1121,7 +1288,7 @@ void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* u
void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* userdata)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_WRITEFUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_WRITEDATA, userdata);
@@ -1130,7 +1297,7 @@ void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* use
void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userdata)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_READFUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_READDATA, userdata);
@@ -1139,7 +1306,7 @@ void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userd
void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void* userdata)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_SSL_CTX_FUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_SSL_CTX_DATA, userdata);
@@ -1148,7 +1315,7 @@ void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void*
void LLCurlEasyRequest::slist_append(const char* str)
{
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->slist_append(str);
}
@@ -1159,7 +1326,7 @@ void LLCurlEasyRequest::sendRequest(const std::string& url)
llassert_always(!mRequestSent);
mRequestSent = true;
lldebugs << url << llendl;
- if (mEasy)
+ if (isValid() && mEasy)
{
mEasy->setHeaders();
mEasy->setoptString(CURLOPT_URL, url);
@@ -1171,7 +1338,7 @@ void LLCurlEasyRequest::requestComplete()
{
llassert_always(mRequestSent);
mRequestSent = false;
- if (mEasy)
+ if (isValid() && mEasy)
{
mMulti->removeEasy(mEasy);
}
@@ -1180,6 +1347,10 @@ void LLCurlEasyRequest::requestComplete()
// Usage: Call getRestult until it returns false (no more messages)
bool LLCurlEasyRequest::getResult(CURLcode* result, LLCurl::TransferInfo* info)
{
+ if(!isValid())
+ {
+ return false ;
+ }
if (!mMulti->isCompleted())
{ //we're busy, try again later
return false;
@@ -1244,7 +1415,7 @@ CURLMsg* LLCurlEasyRequest::info_read(S32* q, LLCurl::TransferInfo* info)
std::string LLCurlEasyRequest::getErrorString()
{
- return mEasy ? std::string(mEasy->getErrorBuffer()) : std::string();
+ return isValid() && mEasy ? std::string(mEasy->getErrorBuffer()) : std::string();
}
////////////////////////////////////////////////////////////////////////////
@@ -1270,8 +1441,11 @@ unsigned long LLCurl::ssl_thread_id(void)
}
#endif
-void LLCurl::initClass(bool multi_threaded)
+void LLCurl::initClass(F32 curl_reuest_timeout, S32 max_number_handles, bool multi_threaded)
{
+ sCurlRequestTimeOut = curl_reuest_timeout ; //seconds
+ sMaxHandles = max_number_handles ; //max number of handles, (multi handles and easy handles combined).
+
// Do not change this "unless you are familiar with and mean to control
// internal operations of libcurl"
// - http://curl.haxx.se/libcurl/c/curl_global_init.html
@@ -1290,10 +1464,17 @@ void LLCurl::initClass(bool multi_threaded)
#endif
sCurlThread = new LLCurlThread(multi_threaded) ;
+ if(multi_threaded)
+ {
+ sHandleMutexp = new LLMutex(NULL) ;
+ Easy::sHandleMutexp = new LLMutex(NULL) ;
+ }
}
void LLCurl::cleanupClass()
{
+ sNotQuitting = false; //set quitting
+
//shut down curl thread
while(1)
{
@@ -1314,14 +1495,85 @@ void LLCurl::cleanupClass()
for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter)
{
CURL* curl = *iter;
- curl_easy_cleanup(curl);
+ LLCurl::deleteEasyHandle(curl);
}
Easy::sFreeHandles.clear();
+ delete Easy::sHandleMutexp ;
+ Easy::sHandleMutexp = NULL ;
+
+ delete sHandleMutexp ;
+ sHandleMutexp = NULL ;
+
llassert(Easy::sActiveHandles.empty());
}
+//static
+CURLM* LLCurl::newMultiHandle()
+{
+ LLMutexLock lock(sHandleMutexp) ;
+
+ if(sTotalHandles + 1 > sMaxHandles)
+ {
+ llwarns << "no more handles available." << llendl ;
+ return NULL ; //failed
+ }
+ sTotalHandles++;
+
+ CURLM* ret = curl_multi_init() ;
+ if(!ret)
+ {
+ llwarns << "curl_multi_init failed." << llendl ;
+ }
+
+ return ret ;
+}
+
+//static
+CURLMcode LLCurl::deleteMultiHandle(CURLM* handle)
+{
+ if(handle)
+ {
+ LLMutexLock lock(sHandleMutexp) ;
+ sTotalHandles-- ;
+ return curl_multi_cleanup(handle) ;
+ }
+ return CURLM_OK ;
+}
+
+//static
+CURL* LLCurl::newEasyHandle()
+{
+ LLMutexLock lock(sHandleMutexp) ;
+
+ if(sTotalHandles + 1 > sMaxHandles)
+ {
+ llwarns << "no more handles available." << llendl ;
+ return NULL ; //failed
+ }
+ sTotalHandles++;
+
+ CURL* ret = curl_easy_init() ;
+ if(!ret)
+ {
+ llwarns << "curl_easy_init failed." << llendl ;
+ }
+
+ return ret ;
+}
+
+//static
+void LLCurl::deleteEasyHandle(CURL* handle)
+{
+ if(handle)
+ {
+ LLMutexLock lock(sHandleMutexp) ;
+ curl_easy_cleanup(handle) ;
+ sTotalHandles-- ;
+ }
+}
+
const unsigned int LLCurl::MAX_REDIRECTS = 5;
// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index a275db3e53..fd664c0fa1 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -43,6 +43,7 @@
#include "llsd.h"
#include "llthread.h"
#include "llqueuedthread.h"
+#include "llframetimer.h"
class LLMutex;
class LLCurlThread;
@@ -162,7 +163,7 @@ public:
/**
* @ brief Initialize LLCurl class
*/
- static void initClass(bool multi_threaded = false);
+ static void initClass(F32 curl_reuest_timeout = 120.f, S32 max_number_handles = 256, bool multi_threaded = false);
/**
* @ brief Cleanup LLCurl class
@@ -182,11 +183,24 @@ public:
static unsigned long ssl_thread_id(void);
static LLCurlThread* getCurlThread() { return sCurlThread ;}
+
+ static CURLM* newMultiHandle() ;
+ static CURLMcode deleteMultiHandle(CURLM* handle) ;
+ static CURL* newEasyHandle() ;
+ static void deleteEasyHandle(CURL* handle) ;
+
private:
static std::string sCAPath;
static std::string sCAFile;
static const unsigned int MAX_REDIRECTS;
static LLCurlThread* sCurlThread;
+
+ static LLMutex* sHandleMutexp ;
+ static S32 sTotalHandles ;
+ static S32 sMaxHandles;
+public:
+ static bool sNotQuitting;
+ static F32 sCurlRequestTimeOut;
};
class LLCurl::Easy
@@ -253,6 +267,7 @@ private:
static std::set<CURL*> sFreeHandles;
static std::set<CURL*> sActiveHandles;
+ static LLMutex* sHandleMutexp ;
};
class LLCurl::Multi
@@ -276,7 +291,7 @@ public:
STATE_COMPLETED=2
} ePerformState;
- Multi();
+ Multi(F32 idle_time_out = 0.f);
LLCurl::Easy* allocEasy();
bool addEasy(LLCurl::Easy* easy);
@@ -287,7 +302,10 @@ public:
void setState(ePerformState state) ;
ePerformState getState() ;
+
bool isCompleted() ;
+ bool isValid() {return mCurlMultiHandle != NULL ;}
+ bool isDead() {return mDead;}
bool waitToComplete() ;
@@ -300,6 +318,7 @@ public:
private:
void easyFree(LLCurl::Easy*);
+ void cleanup() ;
CURLM* mCurlMultiHandle;
@@ -316,6 +335,9 @@ private:
BOOL mDead ;
LLMutex* mMutexp ;
LLMutex* mDeletionMutexp ;
+ LLMutex* mEasyMutexp ;
+ LLFrameTimer mIdleTimer ;
+ F32 mIdleTimeOut;
};
class LLCurlThread : public LLQueuedThread
@@ -344,7 +366,7 @@ public:
LLCurlThread(bool threaded = true) ;
virtual ~LLCurlThread() ;
- S32 update(U32 max_time_ms);
+ S32 update(F32 max_time_ms);
void addMulti(LLCurl::Multi* multi) ;
void killMulti(LLCurl::Multi* multi) ;
@@ -352,6 +374,7 @@ public:
private:
bool doMultiPerform(LLCurl::Multi* multi) ;
void deleteMulti(LLCurl::Multi* multi) ;
+ void cleanupMulti(LLCurl::Multi* multi) ;
} ;
namespace boost
@@ -409,6 +432,7 @@ public:
std::string getErrorString();
bool isCompleted() {return mMulti->isCompleted() ;}
bool wait() { return mMulti->waitToComplete(); }
+ bool isValid() {return mMulti && mMulti->isValid(); }
LLCurl::Easy* getEasy() const { return mEasy; }
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 2bca517e97..612d765969 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -232,7 +232,8 @@ LLSD LLHTTPAssetRequest::getFullDetails() const
void LLHTTPAssetRequest::setupCurlHandle()
{
// *NOTE: Similar code exists in mapserver/llcurlutil.cpp JC
- mCurlHandle = curl_easy_init();
+ mCurlHandle = LLCurl::newEasyHandle();
+ llassert_always(mCurlHandle != NULL) ;
// Apply proxy settings if configured to do so
LLProxy::getInstance()->applyProxySettings(mCurlHandle);
@@ -278,7 +279,7 @@ void LLHTTPAssetRequest::setupCurlHandle()
void LLHTTPAssetRequest::cleanupCurlHandle()
{
- curl_easy_cleanup(mCurlHandle);
+ LLCurl::deleteEasyHandle(mCurlHandle);
if (mAssetStoragep)
{
// Terminating a request. Thus upload or download is no longer pending.
@@ -429,12 +430,13 @@ void LLHTTPAssetStorage::_init(const std::string& web_host, const std::string& l
// curl_global_init moved to LLCurl::initClass()
- mCurlMultiHandle = curl_multi_init();
+ mCurlMultiHandle = LLCurl::newMultiHandle() ;
+ llassert_always(mCurlMultiHandle != NULL) ;
}
LLHTTPAssetStorage::~LLHTTPAssetStorage()
{
- curl_multi_cleanup(mCurlMultiHandle);
+ LLCurl::deleteMultiHandle(mCurlMultiHandle);
mCurlMultiHandle = NULL;
// curl_global_cleanup moved to LLCurl::initClass()
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index dd4e3a6300..231cb7ca8f 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -228,6 +228,12 @@ static void request(
LLPumpIO::chain_t chain;
LLURLRequest* req = new LLURLRequest(method, url);
+ if(!req->isValid())//failed
+ {
+ delete req ;
+ return ;
+ }
+
req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
@@ -423,7 +429,9 @@ static LLSD blocking_request(
{
lldebugs << "blockingRequest of " << url << llendl;
char curl_error_buffer[CURL_ERROR_SIZE] = "\0";
- CURL* curlp = curl_easy_init();
+ CURL* curlp = LLCurl::newEasyHandle();
+ llassert_always(curlp != NULL) ;
+
LLHTTPBuffer http_buffer;
std::string body_str;
@@ -517,7 +525,7 @@ static LLSD blocking_request(
}
// * Cleanup
- curl_easy_cleanup(curlp);
+ LLCurl::deleteEasyHandle(curlp);
return response;
}
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index 73e8a69085..987f386aa3 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -818,6 +818,8 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
// Copy everything after mLast read to the out.
LLBufferArray::segment_iterator_t seg_iter;
+
+ buffer->lock();
seg_iter = buffer->splitAfter(mLastRead);
if(seg_iter != buffer->endSegment())
{
@@ -838,7 +840,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
}
#endif
}
-
+ buffer->unlock();
//
// *FIX: get rid of extra bytes off the end
//
diff --git a/indra/llmessage/lliopipe.cpp b/indra/llmessage/lliopipe.cpp
index 6e4eec74a6..8f827f7a30 100644
--- a/indra/llmessage/lliopipe.cpp
+++ b/indra/llmessage/lliopipe.cpp
@@ -75,6 +75,12 @@ LLIOPipe::~LLIOPipe()
//lldebugs << "destroying LLIOPipe" << llendl;
}
+//virtual
+bool LLIOPipe::isValid()
+{
+ return true ;
+}
+
// static
std::string LLIOPipe::lookupStatusString(EStatus status)
{
diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h
index 8e656b6da1..cbd17b5a3d 100644
--- a/indra/llmessage/lliopipe.h
+++ b/indra/llmessage/lliopipe.h
@@ -231,6 +231,8 @@ public:
*/
virtual ~LLIOPipe();
+ virtual bool isValid() ;
+
protected:
/**
* @brief Base Constructor.
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index 54ceab3422..d5b4d45821 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -445,6 +445,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
// efficient - not only because writev() is better, but also
// because we won't have to do as much work to find the start
// address.
+ buffer->lock();
LLBufferArray::segment_iterator_t it;
LLBufferArray::segment_iterator_t end = buffer->endSegment();
LLSegment segment;
@@ -524,6 +525,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
}
}
+ buffer->unlock();
+
PUMP_DEBUG;
if(done && eos)
{
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index a8d2a0a224..f3ef4f2684 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -195,7 +195,7 @@ bool LLPumpIO::prime(apr_pool_t* pool)
return ((pool == NULL) ? false : true);
}
-bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
+bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
if(chain.empty()) return false;
@@ -204,8 +204,10 @@ bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
LLScopedLock lock(mChainsMutex);
#endif
LLChainInfo info;
+ info.mHasCurlRequest = has_curl_request;
info.setTimeoutSeconds(timeout);
info.mData = LLIOPipe::buffer_ptr_t(new LLBufferArray);
+ info.mData->setThreaded(has_curl_request);
LLLinkInfo link;
#if LL_DEBUG_PIPE_TYPE_IN_PUMP
lldebugs << "LLPumpIO::addChain() " << chain[0] << " '"
@@ -440,6 +442,15 @@ void LLPumpIO::pump()
static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");
+LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain)
+{
+ std::for_each(
+ (*run_chain).mDescriptors.begin(),
+ (*run_chain).mDescriptors.end(),
+ ll_delete_apr_pollset_fd_client_data());
+ return mRunningChains.erase(run_chain);
+}
+
//timeout is in microseconds
void LLPumpIO::pump(const S32& poll_timeout)
{
@@ -585,10 +596,16 @@ void LLPumpIO::pump(const S32& poll_timeout)
// << (*run_chain).mChainLinks[0].mPipe
// << " because we reached the end." << llendl;
#endif
- run_chain = mRunningChains.erase(run_chain);
+ run_chain = removeRunningChain(run_chain);
continue;
}
}
+ else if(isChainExpired(*run_chain))
+ {
+ run_chain = removeRunningChain(run_chain);
+ continue;
+ }
+
PUMP_DEBUG;
if((*run_chain).mLock)
{
@@ -696,11 +713,7 @@ void LLPumpIO::pump(const S32& poll_timeout)
PUMP_DEBUG;
// This chain is done. Clean up any allocated memory and
// erase the chain info.
- std::for_each(
- (*run_chain).mDescriptors.begin(),
- (*run_chain).mDescriptors.end(),
- ll_delete_apr_pollset_fd_client_data());
- run_chain = mRunningChains.erase(run_chain);
+ run_chain = removeRunningChain(run_chain);
// *NOTE: may not always need to rebuild the pollset.
mRebuildPollset = true;
@@ -1095,6 +1108,24 @@ void LLPumpIO::processChain(LLChainInfo& chain)
PUMP_DEBUG;
}
+bool LLPumpIO::isChainExpired(LLChainInfo& chain)
+{
+ if(!chain.mHasCurlRequest)
+ {
+ return false ;
+ }
+
+ for(links_t::iterator iter = chain.mChainLinks.begin(); iter != chain.mChainLinks.end(); ++iter)
+ {
+ if(!(*iter).mPipe->isValid())
+ {
+ return true ;
+ }
+ }
+
+ return false ;
+}
+
bool LLPumpIO::handleChainError(
LLChainInfo& chain,
LLIOPipe::EStatus error)
@@ -1136,6 +1167,9 @@ bool LLPumpIO::handleChainError(
#endif
keep_going = false;
break;
+ case LLIOPipe::STATUS_EXPIRED:
+ keep_going = false;
+ break ;
default:
if(LLIOPipe::isSuccess(error))
{
@@ -1157,7 +1191,8 @@ bool LLPumpIO::handleChainError(
LLPumpIO::LLChainInfo::LLChainInfo() :
mInit(false),
mLock(0),
- mEOS(false)
+ mEOS(false),
+ mHasCurlRequest(false)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);
diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h
index 9303c9d7fc..d2c5d37571 100644
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
@@ -111,9 +111,10 @@ public:
* @param chain The pipes for the chain
* @param timeout The number of seconds in the future to
* expire. Pass in 0.0f to never expire.
+ * @param has_curl_request The chain contains LLURLRequest if true.
* @return Returns true if anything was added to the pump.
*/
- bool addChain(const chain_t& chain, F32 timeout);
+ bool addChain(const chain_t& chain, F32 timeout, bool has_curl_request = false);
/**
* @brief Struct to associate a pipe with it's buffer io indexes.
@@ -356,12 +357,13 @@ protected:
// basic member data
bool mInit;
+ bool mEOS;
+ bool mHasCurlRequest;
S32 mLock;
LLFrameTimer mTimer;
links_t::iterator mHead;
links_t mChainLinks;
- LLIOPipe::buffer_ptr_t mData;
- bool mEOS;
+ LLIOPipe::buffer_ptr_t mData;
LLSD mContext;
// tracking inside the pump
@@ -402,7 +404,7 @@ protected:
protected:
void initialize(apr_pool_t* pool);
void cleanup();
-
+ current_chain_t removeRunningChain(current_chain_t& chain) ;
/**
* @brief Given the internal state of the chains, rebuild the pollset
* @see setConditional()
@@ -429,6 +431,9 @@ protected:
*/
bool handleChainError(LLChainInfo& chain, LLIOPipe::EStatus error);
+ //if the chain is expired, remove it
+ bool isChainExpired(LLChainInfo& chain) ;
+
public:
/**
* @brief Return number of running chains.
diff --git a/indra/llmessage/llsdrpcclient.h b/indra/llmessage/llsdrpcclient.h
index 9fb49a5c33..0cecf4f688 100644
--- a/indra/llmessage/llsdrpcclient.h
+++ b/indra/llmessage/llsdrpcclient.h
@@ -240,9 +240,16 @@ public:
virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
{
lldebugs << "LLSDRPCClientFactory::build" << llendl;
- LLIOPipe::ptr_t service(new Client);
- chain.push_back(service);
LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
+ if(!http->isValid())
+ {
+ llwarns << "Creating LLURLRequest failed." << llendl ;
+ delete http;
+ return false;
+ }
+
+ LLIOPipe::ptr_t service(new Client);
+ chain.push_back(service);
LLIOPipe::ptr_t http_pipe(http);
http->addHeader("Content-Type: text/llsd");
if(mURL.empty())
@@ -283,9 +290,16 @@ public:
virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
{
lldebugs << "LLXMLSDRPCClientFactory::build" << llendl;
- LLIOPipe::ptr_t service(new Client);
- chain.push_back(service);
+
LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
+ if(!http->isValid())
+ {
+ llwarns << "Creating LLURLRequest failed." << llendl ;
+ delete http;
+ return false ;
+ }
+ LLIOPipe::ptr_t service(new Client);
+ chain.push_back(service);
LLIOPipe::ptr_t http_pipe(http);
http->addHeader("Content-Type: text/xml");
if(mURL.empty())
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index a3a2b2b1b8..a16f5c7bf0 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -64,7 +64,7 @@ public:
~LLURLRequestDetail();
std::string mURL;
LLCurlEasyRequest* mCurlRequest;
- LLBufferArray* mResponseBuffer;
+ LLIOPipe::buffer_ptr_t mResponseBuffer;
LLChannelDescriptors mChannels;
U8* mLastRead;
U32 mBodyLimit;
@@ -75,7 +75,6 @@ public:
LLURLRequestDetail::LLURLRequestDetail() :
mCurlRequest(NULL),
- mResponseBuffer(NULL),
mLastRead(NULL),
mBodyLimit(0),
mByteAccumulator(0),
@@ -84,13 +83,18 @@ LLURLRequestDetail::LLURLRequestDetail() :
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mCurlRequest = new LLCurlEasyRequest();
+
+ if(!mCurlRequest->isValid()) //failed.
+ {
+ delete mCurlRequest ;
+ mCurlRequest = NULL ;
+ }
}
LLURLRequestDetail::~LLURLRequestDetail()
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
delete mCurlRequest;
- mResponseBuffer = NULL;
mLastRead = NULL;
}
@@ -252,12 +256,24 @@ void LLURLRequest::allowCookies()
mDetail->mCurlRequest->setoptString(CURLOPT_COOKIEFILE, "");
}
+//virtual
+bool LLURLRequest::isValid()
+{
+ return mDetail->mCurlRequest && mDetail->mCurlRequest->isValid();
+}
+
// virtual
LLIOPipe::EStatus LLURLRequest::handleError(
LLIOPipe::EStatus status,
LLPumpIO* pump)
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
+
+ if(!isValid())
+ {
+ return STATUS_EXPIRED ;
+ }
+
if(mCompletionCallback && pump)
{
LLURLRequestComplete* complete = NULL;
@@ -326,7 +342,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
// *FIX: bit of a hack, but it should work. The configure and
// callback method expect this information to be ready.
- mDetail->mResponseBuffer = buffer.get();
+ mDetail->mResponseBuffer = buffer;
mDetail->mChannels = channels;
if(!configure())
{
@@ -443,6 +459,12 @@ void LLURLRequest::initialize()
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mState = STATE_INITIALIZED;
mDetail = new LLURLRequestDetail;
+
+ if(!isValid())
+ {
+ return ;
+ }
+
mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);
mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this);
diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h
index ec5c2c1941..44d358d906 100644
--- a/indra/llmessage/llurlrequest.h
+++ b/indra/llmessage/llurlrequest.h
@@ -188,6 +188,8 @@ public:
*/
void allowCookies();
+ /*virtual*/ bool isValid() ;
+
public:
/**
* @brief Give this pipe a chance to handle a generated error
diff --git a/indra/llmessage/tests/llsdmessage_test.cpp b/indra/llmessage/tests/llsdmessage_test.cpp
index 0f2c069303..6871ac0d52 100644
--- a/indra/llmessage/tests/llsdmessage_test.cpp
+++ b/indra/llmessage/tests/llsdmessage_test.cpp
@@ -42,6 +42,7 @@
// external library headers
// other Linden headers
#include "../test/lltut.h"
+#include "../test/catch_and_store_what_in.h"
#include "llsdserialize.h"
#include "llevents.h"
#include "stringize.h"
@@ -72,43 +73,14 @@ namespace tut
template<> template<>
void llsdmessage_object::test<1>()
{
- bool threw = false;
+ std::string threw;
// This should fail...
try
{
LLSDMessage localListener;
}
- catch (const LLEventPump::DupPumpName&)
- {
- threw = true;
- }
- catch (const std::runtime_error& ex)
- {
- // This clause is because on Linux, on the viewer side, for this
- // one test program (though not others!), the
- // LLEventPump::DupPumpName exception isn't caught by the clause
- // above. Warn the user...
- std::cerr << "Failed to catch " << typeid(ex).name() << std::endl;
- // But if the expected exception was thrown, allow the test to
- // succeed anyway. Not sure how else to handle this odd case.
- if (std::string(typeid(ex).name()) == typeid(LLEventPump::DupPumpName).name())
- {
- threw = true;
- }
- else
- {
- // We don't even recognize this exception. Let it propagate
- // out to TUT to fail the test.
- throw;
- }
- }
- catch (...)
- {
- std::cerr << "Utterly failed to catch expected exception!" << std::endl;
- // This case is full of fail. We HAVE to address it.
- throw;
- }
- ensure("second LLSDMessage should throw", threw);
+ CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupPumpName)
+ ensure("second LLSDMessage should throw", ! threw.empty());
}
template<> template<>
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 110fac0f23..f10eaee5b4 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -31,6 +31,7 @@
#include "llpluginprocessparent.h"
#include "llpluginmessagepipe.h"
#include "llpluginmessageclasses.h"
+#include "stringize.h"
#include "llapr.h"
@@ -134,7 +135,10 @@ LLPluginProcessParent::~LLPluginProcessParent()
mSharedMemoryRegions.erase(iter);
}
- mProcess.kill();
+ if (mProcess)
+ {
+ mProcess->kill();
+ }
killSockets();
}
@@ -159,8 +163,8 @@ void LLPluginProcessParent::errorState(void)
void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug)
{
- mProcess.setExecutable(launcher_filename);
- mProcess.setWorkingDirectory(plugin_dir);
+ mProcessParams.executable = launcher_filename;
+ mProcessParams.cwd = plugin_dir;
mPluginFile = plugin_filename;
mPluginDir = plugin_dir;
mCPUUsage = 0.0f;
@@ -371,10 +375,8 @@ void LLPluginProcessParent::idle(void)
// Launch the plugin process.
// Only argument to the launcher is the port number we're listening on
- std::stringstream stream;
- stream << mBoundPort;
- mProcess.addArgument(stream.str());
- if(mProcess.launch() != 0)
+ mProcessParams.args.add(stringize(mBoundPort));
+ if (! (mProcess = LLProcess::create(mProcessParams)))
{
errorState();
}
@@ -388,19 +390,18 @@ void LLPluginProcessParent::idle(void)
// The command we're constructing would look like this on the command line:
// osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell'
- std::stringstream cmd;
-
- mDebugger.setExecutable("/usr/bin/osascript");
- mDebugger.addArgument("-e");
- mDebugger.addArgument("tell application \"Terminal\"");
- mDebugger.addArgument("-e");
- cmd << "set win to do script \"gdb -pid " << mProcess.getProcessID() << "\"";
- mDebugger.addArgument(cmd.str());
- mDebugger.addArgument("-e");
- mDebugger.addArgument("do script \"continue\" in win");
- mDebugger.addArgument("-e");
- mDebugger.addArgument("end tell");
- mDebugger.launch();
+ LLProcess::Params params;
+ params.executable = "/usr/bin/osascript";
+ params.args.add("-e");
+ params.args.add("tell application \"Terminal\"");
+ params.args.add("-e");
+ params.args.add(STRINGIZE("set win to do script \"gdb -pid "
+ << mProcess->getProcessID() << "\""));
+ params.args.add("-e");
+ params.args.add("do script \"continue\" in win");
+ params.args.add("-e");
+ params.args.add("end tell");
+ mDebugger = LLProcess::create(params);
#endif
}
@@ -470,7 +471,7 @@ void LLPluginProcessParent::idle(void)
break;
case STATE_EXITING:
- if(!mProcess.isRunning())
+ if (! mProcess->isRunning())
{
setState(STATE_CLEANUP);
}
@@ -498,7 +499,7 @@ void LLPluginProcessParent::idle(void)
break;
case STATE_CLEANUP:
- mProcess.kill();
+ mProcess->kill();
killSockets();
setState(STATE_DONE);
break;
@@ -1077,7 +1078,7 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit()
{
bool result = false;
- if(!mProcess.isRunning())
+ if (! mProcess->isRunning())
{
LL_WARNS("Plugin") << "child exited" << LL_ENDL;
result = true;
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index c66723f175..990fc5cbae 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -30,13 +30,14 @@
#define LL_LLPLUGINPROCESSPARENT_H
#include "llapr.h"
-#include "llprocesslauncher.h"
+#include "llprocess.h"
#include "llpluginmessage.h"
#include "llpluginmessagepipe.h"
#include "llpluginsharedmemory.h"
#include "lliosocket.h"
#include "llthread.h"
+#include "llsd.h"
class LLPluginProcessParentOwner
{
@@ -139,26 +140,27 @@ private:
};
EState mState;
void setState(EState state);
-
+
bool pluginLockedUp();
bool pluginLockedUpOrQuit();
bool accept();
-
+
LLSocket::ptr_t mListenSocket;
LLSocket::ptr_t mSocket;
U32 mBoundPort;
-
- LLProcessLauncher mProcess;
-
+
+ LLProcess::Params mProcessParams;
+ LLProcessPtr mProcess;
+
std::string mPluginFile;
std::string mPluginDir;
LLPluginProcessParentOwner *mOwner;
-
+
typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType;
sharedMemoryRegionsType mSharedMemoryRegions;
-
+
LLSD mMessageClassVersions;
std::string mPluginVersionString;
@@ -171,7 +173,7 @@ private:
bool mBlocked;
bool mPolledInput;
- LLProcessLauncher mDebugger;
+ LLProcessPtr mDebugger;
F32 mPluginLaunchTimeout; // Somewhat longer timeout for initial launch.
F32 mPluginLockupTimeout; // If we don't receive a heartbeat in this many seconds, we declare the plugin locked up.
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 5a6f3d8292..6b2852670a 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -66,7 +66,7 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
LLShaderFeatures::LLShaderFeatures()
: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false),
-hasGamma(false), hasLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false),
+hasGamma(false), hasLighting(false), isAlphaLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false),
hasAlphaMask(false)
{
}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 2a6c050eac..00b4b0dbd4 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -36,6 +36,7 @@ public:
bool calculatesLighting;
bool calculatesAtmospherics;
bool hasLighting; // implies no transport (it's possible to have neither though)
+ bool isAlphaLighting; // indicates lighting shaders need not be linked in (lighting performed directly in alpha shader to match deferred lighting functions)
bool isShiny;
bool isFullbright; // implies no lighting
bool isSpecular;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index cd827f5091..b0ddacbb05 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -997,7 +997,7 @@ void LLLightState::setSpotDirection(const LLVector3& direction)
const glh::matrix4f& mat = gGL.getModelviewMatrix();
mat.mult_matrix_dir(dir);
- mSpotDirection.set(direction);
+ mSpotDirection.set(dir.v);
}
}
@@ -1434,6 +1434,8 @@ void LLRender::loadIdentity()
flush();
{
+ llassert_always(mMatrixMode < NUM_MATRIX_MODES) ;
+
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity();
mMatHash[mMatrixMode]++;
}
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 1aa12614ea..ef2a7395da 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -457,7 +457,8 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
gGL.flush();
if (!source.mFBO || !mFBO)
{
- llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
+ llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
+ return;
}
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index ac9dc9544d..1a03aeebb7 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -107,10 +107,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
return FALSE;
}
-
- if (!shader->attachObject("lighting/sumLightsSpecularV.glsl"))
+
+ if (!features->isAlphaLighting)
{
- return FALSE;
+ if (!shader->attachObject("lighting/sumLightsSpecularV.glsl"))
+ {
+ return FALSE;
+ }
}
if (!shader->attachObject("lighting/lightSpecularV.glsl"))
@@ -125,9 +128,12 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
return FALSE;
}
- if (!shader->attachObject("lighting/sumLightsV.glsl"))
+ if (!features->isAlphaLighting)
{
- return FALSE;
+ if (!shader->attachObject("lighting/sumLightsV.glsl"))
+ {
+ return FALSE;
+ }
}
if (!shader->attachObject("lighting/lightV.glsl"))
@@ -296,7 +302,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
- }
+ }
}
// NOTE order of shader object attaching is VERY IMPORTANT!!!
@@ -579,7 +585,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
text[count++] = strdup("#define ATTRIBUTE attribute\n");
text[count++] = strdup("#define VARYING varying\n");
}
- else if (version < 3.f)
+ else if (version < 3.3f)
{
//set version to 1.20
text[count++] = strdup("#version 120\n");
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 20a450fbfb..eb302392bb 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -148,7 +148,7 @@ U32 wpo2(U32 i)
return r;
}
-U8* LLVBOPool::allocate(U32& name, U32 size)
+volatile U8* LLVBOPool::allocate(U32& name, U32 size)
{
llassert(nhpo2(size) == size);
@@ -159,20 +159,25 @@ U8* LLVBOPool::allocate(U32& name, U32 size)
mFreeList.resize(i+1);
}
- U8* ret = NULL;
+ volatile U8* ret = NULL;
if (mFreeList[i].empty())
{
//make a new buffer
glGenBuffersARB(1, &name);
glBindBufferARB(mType, name);
- glBufferDataARB(mType, size, 0, mUsage);
LLVertexBuffer::sAllocatedBytes += size;
- if (LLVertexBuffer::sDisableVBOMapping)
+ if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
{
+ glBufferDataARB(mType, size, 0, mUsage);
ret = (U8*) ll_aligned_malloc_16(size);
}
+ else
+ { //always use a true hint of static draw when allocating non-client-backed buffers
+ glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
+ }
+
glBindBufferARB(mType, 0);
}
else
@@ -188,7 +193,7 @@ U8* LLVBOPool::allocate(U32& name, U32 size)
return ret;
}
-void LLVBOPool::release(U32 name, U8* buffer, U32 size)
+void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
{
llassert(nhpo2(size) == size);
@@ -201,8 +206,15 @@ void LLVBOPool::release(U32 name, U8* buffer, U32 size)
rec.mClientData = buffer;
sBytesPooled += size;
-
- mFreeList[i].push_back(rec);
+
+ if (!LLVertexBuffer::sDisableVBOMapping && mUsage == GL_DYNAMIC_DRAW_ARB)
+ {
+ glDeleteBuffersARB(1, &rec.mGLName);
+ }
+ else
+ {
+ mFreeList[i].push_back(rec);
+ }
}
void LLVBOPool::cleanup()
@@ -221,7 +233,7 @@ void LLVBOPool::cleanup()
if (r.mClientData)
{
- ll_aligned_free_16(r.mClientData);
+ ll_aligned_free_16((void*) r.mClientData);
}
l.pop_front();
@@ -536,7 +548,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
{
validateRange(start, end, count, indices_offset);
-
+ mMappable = FALSE;
gGL.syncMatrices();
llassert(mNumVerts >= 0);
@@ -591,7 +603,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
-
+ mMappable = FALSE;
gGL.syncMatrices();
llassert(mNumIndices >= 0);
@@ -637,7 +649,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
-
+ mMappable = FALSE;
gGL.syncMatrices();
llassert(mNumVerts >= 0);
@@ -787,9 +799,26 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
if (mUsage && mUsage != GL_STREAM_DRAW_ARB)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
- mUsage = GL_DYNAMIC_DRAW_ARB;
+ if (sDisableVBOMapping)
+ { //always use stream draw if VBO mapping is disabled
+ mUsage = GL_STREAM_DRAW_ARB;
+ }
+ else
+ {
+ mUsage = GL_DYNAMIC_DRAW_ARB;
+ }
}
-
+
+
+ if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping)
+ {
+ mMappable = TRUE;
+ }
+ else
+ {
+ mMappable = FALSE;
+ }
+
//zero out offsets
for (U32 i = 0; i < TYPE_MAX; i++)
{
@@ -1042,7 +1071,7 @@ void LLVertexBuffer::destroyGLBuffer()
}
else
{
- FREE_MEM(sPrivatePoolp, mMappedData) ;
+ FREE_MEM(sPrivatePoolp, (void*) mMappedData) ;
mMappedData = NULL;
mEmpty = TRUE;
}
@@ -1063,7 +1092,7 @@ void LLVertexBuffer::destroyGLIndices()
}
else
{
- FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
+ FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData) ;
mMappedIndexData = NULL;
mEmpty = TRUE;
}
@@ -1282,8 +1311,11 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
return true;
}
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER_RANGE("VBO Map Range");
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER("VBO Map");
+
// Map for data access
-U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
+volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
{
bindGLBuffer(true);
LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
@@ -1298,7 +1330,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
if (useVBOs())
{
- if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
+ if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (count == -1)
{
@@ -1323,7 +1355,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
if (!mapped)
{
//not already mapped, map new region
- MappedRegion region(type, !sDisableVBOMapping && map_range ? -1 : index, count);
+ MappedRegion region(type, mMappable && map_range ? -1 : index, count);
mMappedVertexRegions.push_back(region);
}
}
@@ -1340,19 +1372,20 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
sMappedCount++;
stop_glerror();
- if(sDisableVBOMapping)
+ if(!mMappable)
{
map_range = false;
}
else
{
- U8* src = NULL;
+ volatile U8* src = NULL;
waitFence();
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
+ LLFastTimer t(FTM_VBO_MAP_BUFFER_RANGE);
S32 offset = mOffsets[type] + sTypeSize[type]*index;
S32 length = (sTypeSize[type]*count+0xF) & ~0xF;
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length,
@@ -1376,6 +1409,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
}
}
+ LLFastTimer t(FTM_VBO_MAP_BUFFER);
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1403,7 +1437,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
llassert(src != NULL);
- mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
+ mMappedData = LL_NEXT_ALIGNED_ADDRESS<volatile U8>(src);
mAlignedOffset = mMappedData - src;
stop_glerror();
@@ -1416,7 +1450,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
//check the availability of memory
LLMemory::logMemoryInfo(TRUE) ;
- if(!sDisableVBOMapping)
+ if(mMappable)
{
//--------------------
//print out more debug info before crash
@@ -1448,7 +1482,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
map_range = false;
}
- if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
+ if (map_range && gGLManager.mHasMapBufferRange && mMappable)
{
return mMappedData;
}
@@ -1458,7 +1492,11 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
}
}
-U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
+
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX_RANGE("IBO Map Range");
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map");
+
+volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
bindGLIndices(true);
@@ -1473,7 +1511,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if (useVBOs())
{
- if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
+ if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (count == -1)
{
@@ -1495,7 +1533,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if (!mapped)
{
//not already mapped, map new region
- MappedRegion region(TYPE_INDEX, !sDisableVBOMapping && map_range ? -1 : index, count);
+ MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : index, count);
mMappedIndexRegions.push_back(region);
}
}
@@ -1524,19 +1562,20 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
}
}
- if(sDisableVBOMapping)
+ if(!mMappable)
{
map_range = false;
}
else
{
- U8* src = NULL;
+ volatile U8* src = NULL;
waitFence();
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
+ LLFastTimer t(FTM_VBO_MAP_INDEX_RANGE);
S32 offset = sizeof(U16)*index;
S32 length = sizeof(U16)*count;
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length,
@@ -1548,6 +1587,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
else
{
#ifdef GL_ARB_map_buffer_range
+ LLFastTimer t(FTM_VBO_MAP_INDEX);
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1569,6 +1609,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
}
else
{
+ LLFastTimer t(FTM_VBO_MAP_INDEX);
map_range = false;
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
@@ -1587,7 +1628,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
log_glerror();
LLMemory::logMemoryInfo(TRUE) ;
- if(!sDisableVBOMapping)
+ if(mMappable)
{
GLint buff;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
@@ -1609,7 +1650,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
map_range = false;
}
- if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
+ if (map_range && gGLManager.mHasMapBufferRange && mMappable)
{
return mMappedIndexData;
}
@@ -1619,6 +1660,13 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
}
}
+static LLFastTimer::DeclareTimer FTM_VBO_UNMAP("VBO Unmap");
+static LLFastTimer::DeclareTimer FTM_VBO_FLUSH_RANGE("Flush VBO Range");
+
+
+static LLFastTimer::DeclareTimer FTM_IBO_UNMAP("IBO Unmap");
+static LLFastTimer::DeclareTimer FTM_IBO_FLUSH_RANGE("Flush IBO Range");
+
void LLVertexBuffer::unmapBuffer()
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
@@ -1631,10 +1679,11 @@ void LLVertexBuffer::unmapBuffer()
if (mMappedData && mVertexLocked)
{
+ LLFastTimer t(FTM_VBO_UNMAP);
bindGLBuffer(true);
updated_all = mIndexLocked; //both vertex and index buffers done updating
- if(sDisableVBOMapping)
+ if(!mMappable)
{
if (!mMappedVertexRegions.empty())
{
@@ -1644,7 +1693,7 @@ void LLVertexBuffer::unmapBuffer()
const MappedRegion& region = mMappedVertexRegions[i];
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
S32 length = sTypeSize[region.mType]*region.mCount;
- glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, mMappedData+offset);
+ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset);
stop_glerror();
}
@@ -1653,7 +1702,7 @@ void LLVertexBuffer::unmapBuffer()
else
{
stop_glerror();
- glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
+ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (U8*) mMappedData);
stop_glerror();
}
}
@@ -1671,6 +1720,7 @@ void LLVertexBuffer::unmapBuffer()
S32 length = sTypeSize[region.mType]*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
+ LLFastTimer t(FTM_VBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
#endif
@@ -1698,8 +1748,9 @@ void LLVertexBuffer::unmapBuffer()
if (mMappedIndexData && mIndexLocked)
{
+ LLFastTimer t(FTM_IBO_UNMAP);
bindGLIndices();
- if(sDisableVBOMapping)
+ if(!mMappable)
{
if (!mMappedIndexRegions.empty())
{
@@ -1708,7 +1759,7 @@ void LLVertexBuffer::unmapBuffer()
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
- glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, mMappedIndexData+offset);
+ glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset);
stop_glerror();
}
@@ -1717,7 +1768,7 @@ void LLVertexBuffer::unmapBuffer()
else
{
stop_glerror();
- glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
+ glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (U8*) mMappedIndexData);
stop_glerror();
}
}
@@ -1734,6 +1785,7 @@ void LLVertexBuffer::unmapBuffer()
S32 length = sizeof(U16)*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
+ LLFastTimer t(FTM_IBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
#endif
@@ -1778,7 +1830,7 @@ template <class T,S32 type> struct VertexBufferStrider
{
if (type == LLVertexBuffer::TYPE_INDEX)
{
- U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
+ volatile U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
if (ptr == NULL)
{
@@ -1794,7 +1846,7 @@ template <class T,S32 type> struct VertexBufferStrider
{
S32 stride = LLVertexBuffer::sTypeSize[type];
- U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
+ volatile U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
if (ptr == NULL)
{
@@ -2109,7 +2161,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER);
stop_glerror();
- U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
+ volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
/*if ((data_mask & mTypeMask) != data_mask)
{
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 3e6f6a959a..e1cbfd3b61 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -60,10 +60,10 @@ public:
U32 mType;
//size MUST be a power of 2
- U8* allocate(U32& name, U32 size);
+ volatile U8* allocate(U32& name, U32 size);
//size MUST be the size provided to allocate that returned the given name
- void release(U32 name, U8* buffer, U32 size);
+ void release(U32 name, volatile U8* buffer, U32 size);
//destroy all records in mFreeList
void cleanup();
@@ -72,7 +72,7 @@ public:
{
public:
U32 mGLName;
- U8* mClientData;
+ volatile U8* mClientData;
};
typedef std::list<Record> record_list_t;
@@ -208,8 +208,8 @@ public:
LLVertexBuffer(U32 typemask, S32 usage);
// map for data access
- U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
- U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
+ volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
+ volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
// set for rendering
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
@@ -244,16 +244,17 @@ public:
S32 getNumVerts() const { return mNumVerts; }
S32 getNumIndices() const { return mNumIndices; }
- U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
- U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
+ volatile U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
+ volatile U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
U32 getTypeMask() const { return mTypeMask; }
bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); }
S32 getSize() const;
S32 getIndicesSize() const { return mIndicesSize; }
- U8* getMappedData() const { return mMappedData; }
- U8* getMappedIndices() const { return mMappedIndexData; }
+ volatile U8* getMappedData() const { return mMappedData; }
+ volatile U8* getMappedIndices() const { return mMappedIndexData; }
S32 getOffset(S32 type) const { return mOffsets[type]; }
S32 getUsage() const { return mUsage; }
+ BOOL isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? TRUE : FALSE; }
void draw(U32 mode, U32 count, U32 indices_offset) const;
void drawArrays(U32 mode, U32 offset, U32 count) const;
@@ -278,12 +279,13 @@ protected:
U32 mGLIndices; // GL IBO handle
U32 mGLArray; // GL VAO handle
- U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
- U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
+ volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
+ volatile U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory
BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory
BOOL mFinal; // if TRUE, buffer can not be mapped again
BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
+ mutable BOOL mMappable; // if TRUE, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
S32 mOffsets[TYPE_MAX];
std::vector<MappedRegion> mMappedVertexRegions;
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 772f173f17..20c3456a56 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -12,7 +12,6 @@ include(LLRender)
include(LLWindow)
include(LLVFS)
include(LLXML)
-include(LLXUIXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
@@ -24,7 +23,6 @@ include_directories(
${LLWINDOW_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
- ${LLXUIXML_INCLUDE_DIRS}
)
set(llui_SOURCE_FILES
@@ -83,7 +81,6 @@ set(llui_SOURCE_FILES
llscrolllistcolumn.cpp
llscrolllistctrl.cpp
llscrolllistitem.cpp
- llsdparam.cpp
llsearcheditor.cpp
llslider.cpp
llsliderctrl.cpp
@@ -100,11 +97,13 @@ set(llui_SOURCE_FILES
lltextutil.cpp
lltextvalidate.cpp
lltimectrl.cpp
+ lltrans.cpp
lltransutil.cpp
lltoggleablemenu.cpp
lltoolbar.cpp
lltooltip.cpp
llui.cpp
+ lluicolor.cpp
lluicolortable.cpp
lluictrl.cpp
lluictrlfactory.cpp
@@ -121,6 +120,7 @@ set(llui_SOURCE_FILES
llview.cpp
llviewquery.cpp
llwindowshade.cpp
+ llxuiparser.cpp
)
set(llui_HEADER_FILES
@@ -189,7 +189,6 @@ set(llui_HEADER_FILES
llscrolllistcolumn.h
llscrolllistctrl.h
llscrolllistitem.h
- llsdparam.h
llsliderctrl.h
llslider.h
llspinctrl.h
@@ -208,6 +207,7 @@ set(llui_HEADER_FILES
lltoggleablemenu.h
lltoolbar.h
lltooltip.h
+ lltrans.h
lltransutil.h
lluicolortable.h
lluiconstants.h
@@ -215,6 +215,7 @@ set(llui_HEADER_FILES
lluictrl.h
lluifwd.h
llui.h
+ lluicolor.h
lluiimage.h
lluistring.h
llundo.h
@@ -228,6 +229,7 @@ set(llui_HEADER_FILES
llview.h
llviewquery.h
llwindowshade.h
+ llxuiparser.h
)
set_source_files_properties(${llui_HEADER_FILES}
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 93d8282aa7..f0d92d597a 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -589,15 +589,23 @@ void LLButton::getOverlayImageSize(S32& overlay_width, S32& overlay_height)
// virtual
void LLButton::draw()
{
+ static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
bool flash = FALSE;
- if( mFlashing )
+ if( mFlashing)
{
- F32 elapsed = mFlashingTimer.getElapsedTimeF32();
- S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
- // flash on or off?
- flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
+ if ( sEnableButtonFlashing)
+ {
+ F32 elapsed = mFlashingTimer.getElapsedTimeF32();
+ S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
+ // flash on or off?
+ flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
+ }
+ else
+ { // otherwise just highlight button in flash color
+ flash = true;
+ }
}
bool pressed_by_keyboard = FALSE;
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 0e7060e22c..2f1c2a47c9 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -34,6 +34,10 @@
#include "llpanel.h"
#include "llresizebar.h"
#include "llcriticaldamp.h"
+#include "boost/foreach.hpp"
+
+static const F32 MIN_FRACTIONAL_SIZE = 0.0001f;
+static const F32 MAX_FRACTIONAL_SIZE = 1.f;
static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");
static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layout_panel("layout_panel");
@@ -49,39 +53,29 @@ void LLLayoutStack::OrientationNames::declareValues()
//
LLLayoutPanel::Params::Params()
: expanded_min_dim("expanded_min_dim", 0),
- min_dim("min_dim", 0),
- max_dim("max_dim", S32_MAX),
- user_resize("user_resize", true),
+ min_dim("min_dim", -1),
+ user_resize("user_resize", false),
auto_resize("auto_resize", true)
{
addSynonym(min_dim, "min_width");
addSynonym(min_dim, "min_height");
- addSynonym(max_dim, "max_width");
- addSynonym(max_dim, "max_height");
}
LLLayoutPanel::LLLayoutPanel(const Params& p)
: LLPanel(p),
- mExpandedMinDimSpecified(false),
- mExpandedMinDim(p.min_dim),
+ mExpandedMinDim(p.expanded_min_dim.isProvided() ? p.expanded_min_dim : p.min_dim),
mMinDim(p.min_dim),
- mMaxDim(p.max_dim),
mAutoResize(p.auto_resize),
mUserResize(p.user_resize),
mCollapsed(FALSE),
mCollapseAmt(0.f),
mVisibleAmt(1.f), // default to fully visible
mResizeBar(NULL),
- mFractionalSize(0.f),
+ mFractionalSize(MIN_FRACTIONAL_SIZE),
+ mTargetDim(0),
+ mIgnoreReshape(false),
mOrientation(LLLayoutStack::HORIZONTAL)
{
- // Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value
- if (p.expanded_min_dim.isProvided())
- {
- mExpandedMinDimSpecified = true;
- mExpandedMinDim = p.expanded_min_dim();
- }
-
// panels initialized as hidden should not start out partially visible
if (!getVisible())
{
@@ -103,33 +97,83 @@ LLLayoutPanel::~LLLayoutPanel()
mResizeBar = NULL;
}
-void LLLayoutPanel::reshape(S32 width, S32 height, BOOL called_from_parent)
+F32 LLLayoutPanel::getAutoResizeFactor() const
+{
+ return mVisibleAmt * (1.f - mCollapseAmt);
+}
+
+F32 LLLayoutPanel::getVisibleAmount() const
+{
+ return mVisibleAmt;
+}
+
+S32 LLLayoutPanel::getLayoutDim() const
+{
+ return llround((F32)((mOrientation == LLLayoutStack::HORIZONTAL)
+ ? getRect().getWidth()
+ : getRect().getHeight()));
+}
+
+S32 LLLayoutPanel::getVisibleDim() const
+{
+ F32 min_dim = getRelevantMinDim();
+ return llround(mVisibleAmt
+ * (min_dim
+ + (((F32)mTargetDim - min_dim) * (1.f - mCollapseAmt))));
+}
+
+void LLLayoutPanel::setOrientation( LLLayoutStack::ELayoutOrientation orientation )
+{
+ mOrientation = orientation;
+ S32 layout_dim = llround((F32)((mOrientation == LLLayoutStack::HORIZONTAL)
+ ? getRect().getWidth()
+ : getRect().getHeight()));
+
+ mTargetDim = llmax(layout_dim, getMinDim());
+}
+
+void LLLayoutPanel::setVisible( BOOL visible )
{
- if (mOrientation == LLLayoutStack::HORIZONTAL)
+ if (visible != getVisible())
{
- mFractionalSize += width - llround(mFractionalSize);
+ LLLayoutStack* stackp = dynamic_cast<LLLayoutStack*>(getParent());
+ if (stackp)
+ {
+ stackp->mNeedsLayout = true;
+ }
}
- else
+ LLPanel::setVisible(visible);
+}
+
+void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= TRUE*/ )
+{
+ if (width == getRect().getWidth() && height == getRect().getHeight()) return;
+
+ if (!mIgnoreReshape && mAutoResize == false)
{
- mFractionalSize += height - llround(mFractionalSize);
+ mTargetDim = (mOrientation == LLLayoutStack::HORIZONTAL) ? width : height;
+ LLLayoutStack* stackp = dynamic_cast<LLLayoutStack*>(getParent());
+ if (stackp)
+ {
+ stackp->mNeedsLayout = true;
+ }
}
LLPanel::reshape(width, height, called_from_parent);
}
-F32 LLLayoutPanel::getCollapseFactor()
+void LLLayoutPanel::handleReshape(const LLRect& new_rect, bool by_user)
{
- if (mOrientation == LLLayoutStack::HORIZONTAL)
+ LLLayoutStack* stackp = dynamic_cast<LLLayoutStack*>(getParent());
+ if (stackp)
{
- F32 collapse_amt =
- clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getWidth()));
- return mVisibleAmt * collapse_amt;
- }
- else
- {
- F32 collapse_amt =
- clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getHeight())));
- return mVisibleAmt * collapse_amt;
+ stackp->mNeedsLayout = true;
+ if (by_user)
+ {
+ // tell layout stack to account for new shape
+ stackp->updatePanelRect(this, new_rect);
+ }
}
+ LLPanel::handleReshape(new_rect, by_user);
}
//
@@ -142,20 +186,21 @@ LLLayoutStack::Params::Params()
clip("clip", true),
open_time_constant("open_time_constant", 0.02f),
close_time_constant("close_time_constant", 0.03f),
+ resize_bar_overlap("resize_bar_overlap", 1),
border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0))
{}
LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)
: LLView(p),
- mMinWidth(0),
- mMinHeight(0),
mPanelSpacing(p.border_size),
mOrientation(p.orientation),
mAnimate(p.animate),
mAnimatedThisFrame(false),
+ mNeedsLayout(true),
mClip(p.clip),
mOpenTimeConstant(p.open_time_constant),
- mCloseTimeConstant(p.close_time_constant)
+ mCloseTimeConstant(p.close_time_constant),
+ mResizeBarOverlap(p.resize_bar_overlap)
{}
LLLayoutStack::~LLLayoutStack()
@@ -169,26 +214,26 @@ void LLLayoutStack::draw()
{
updateLayout();
- e_panel_list_t::iterator panel_it;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ // always clip to stack itself
+ LLLocalClipRect clip(getLocalRect());
+ BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
{
// clip to layout rectangle, not bounding rectangle
- LLRect clip_rect = (*panel_it)->getRect();
+ LLRect clip_rect = panelp->getRect();
// scale clipping rectangle by visible amount
if (mOrientation == HORIZONTAL)
{
- clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor());
+ clip_rect.mRight = clip_rect.mLeft + panelp->getVisibleDim();
}
else
{
- clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor());
+ clip_rect.mBottom = clip_rect.mTop - panelp->getVisibleDim();
}
- LLPanel* panelp = (*panel_it);
-
- LLLocalClipRect clip(clip_rect, mClip);
- // only force drawing invisible children if visible amount is non-zero
- drawChild(panelp, 0, 0, !clip_rect.isEmpty());
+ {LLLocalClipRect clip(clip_rect, mClip);
+ // only force drawing invisible children if visible amount is non-zero
+ drawChild(panelp, 0, 0, !clip_rect.isEmpty());
+ }
}
mAnimatedThisFrame = false;
}
@@ -201,12 +246,10 @@ void LLLayoutStack::removeChild(LLView* view)
{
mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
delete embedded_panelp;
+ updateFractionalSizes();
+ mNeedsLayout = true;
}
- // need to update resizebars
-
- calcMinExtents();
-
LLView::removeChild(view);
}
@@ -221,29 +264,15 @@ bool LLLayoutStack::addChild(LLView* child, S32 tab_group)
LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child);
if (panelp)
{
- panelp->mFractionalSize = (mOrientation == HORIZONTAL)
- ? panelp->getRect().getWidth()
- : panelp->getRect().getHeight();
panelp->setOrientation(mOrientation);
mPanels.push_back(panelp);
+ createResizeBar(panelp);
+ mNeedsLayout = true;
}
- return LLView::addChild(child, tab_group);
-}
+ BOOL result = LLView::addChild(child, tab_group);
-void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front)
-{
- LLLayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move);
- LLLayoutPanel* embedded_target_panel = move_to_front ? *mPanels.begin() : findEmbeddedPanel(target_panel);
-
- if (!embedded_panel_to_move || !embedded_target_panel || embedded_panel_to_move == embedded_target_panel)
- {
- llwarns << "One of the panels was not found in stack or NULL was passed instead of valid panel" << llendl;
- return;
- }
- e_panel_list_t::iterator it = std::find(mPanels.begin(), mPanels.end(), embedded_panel_to_move);
- mPanels.erase(it);
- it = move_to_front ? mPanels.begin() : std::find(mPanels.begin(), mPanels.end(), embedded_target_panel);
- mPanels.insert(it, embedded_panel_to_move);
+ updateFractionalSizes();
+ return result;
}
void LLLayoutStack::addPanel(LLLayoutPanel* panel, EAnimate animate)
@@ -258,84 +287,274 @@ void LLLayoutStack::addPanel(LLLayoutPanel* panel, EAnimate animate)
}
}
-void LLLayoutStack::removePanel(LLPanel* panel)
-{
- removeChild(panel);
-}
-
void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed)
{
LLLayoutPanel* panel_container = findEmbeddedPanel(panel);
if (!panel_container) return;
panel_container->mCollapsed = collapsed;
+ mNeedsLayout = true;
}
-void LLLayoutStack::updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize)
-{
- LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name);
+static LLFastTimer::DeclareTimer FTM_UPDATE_LAYOUT("Update LayoutStacks");
- if (panel)
+void LLLayoutStack::updateLayout()
+{
+ LLFastTimer ft(FTM_UPDATE_LAYOUT);
+
+ if (!mNeedsLayout) return;
+
+ bool animation_in_progress = animatePanels();
+ F32 total_visible_fraction = 0.f;
+ F32 total_open_fraction = 0.f;
+ S32 space_to_distribute = (mOrientation == HORIZONTAL)
+ ? getRect().getWidth()
+ : getRect().getHeight();
+
+ // first, assign minimum dimensions
+ LLLayoutPanel* panelp = NULL;
+ BOOST_FOREACH(panelp, mPanels)
{
- panel->mAutoResize = auto_resize;
+ if (panelp->mAutoResize)
+ {
+ panelp->mTargetDim = panelp->getRelevantMinDim();
+ if (!panelp->mCollapsed && panelp->getVisible())
+ {
+ total_open_fraction += panelp->mFractionalSize;
+ }
+ }
+ space_to_distribute -= panelp->getVisibleDim() + llround((F32)mPanelSpacing * panelp->getVisibleAmount());
+ total_visible_fraction += panelp->mFractionalSize;
}
-}
-void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_resize)
+ llassert(total_visible_fraction < 1.01f);
+
+ // don't need spacing after last panel
+ space_to_distribute += panelp ? llround((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0;
+
+ F32 fraction_distributed = 0.f;
+ if (space_to_distribute > 0 && total_visible_fraction > 0.f)
+ { // give space proportionally to visible auto resize panels
+ BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
+ {
+ if (panelp->mAutoResize)
+ {
+ F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction);
+ S32 delta = llround((F32)space_to_distribute * fraction_to_distribute);
+ fraction_distributed += fraction_to_distribute;
+ panelp->mTargetDim += delta;
+ }
+ }
+ }
+
+ if (fraction_distributed < total_visible_fraction)
+ { // distribute any left over pixels to non-collapsed, visible panels
+ F32 fraction_left = total_visible_fraction - fraction_distributed;
+ S32 space_left = llround((F32)space_to_distribute * (fraction_left / total_visible_fraction));
+
+ BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
+ {
+ if (panelp->mAutoResize
+ && !panelp->mCollapsed
+ && panelp->getVisible())
+ {
+ S32 space_for_panel = llmax(0, llround((F32)space_left * (panelp->mFractionalSize / total_open_fraction)));
+ panelp->mTargetDim += space_for_panel;
+ space_left -= space_for_panel;
+ total_open_fraction -= panelp->mFractionalSize;
+ }
+ }
+ }
+
+ F32 cur_pos = (mOrientation == HORIZONTAL) ? 0.f : (F32)getRect().getHeight();
+
+ BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
+ {
+ F32 panel_dim = llmax(panelp->getExpandedMinDim(), panelp->mTargetDim);
+ F32 panel_visible_dim = panelp->getVisibleDim();
+
+ LLRect panel_rect;
+ if (mOrientation == HORIZONTAL)
+ {
+ panel_rect.setLeftTopAndSize(llround(cur_pos),
+ getRect().getHeight(),
+ llround(panel_dim),
+ getRect().getHeight());
+ }
+ else
+ {
+ panel_rect.setLeftTopAndSize(0,
+ llround(cur_pos),
+ getRect().getWidth(),
+ llround(panel_dim));
+ }
+ panelp->setIgnoreReshape(true);
+ panelp->setShape(panel_rect);
+ panelp->setIgnoreReshape(false);
+
+ LLRect resize_bar_rect(panel_rect);
+
+ F32 panel_spacing = (F32)mPanelSpacing * panelp->getVisibleAmount();
+ if (mOrientation == HORIZONTAL)
+ {
+ resize_bar_rect.mLeft = panel_rect.mRight - mResizeBarOverlap;
+ resize_bar_rect.mRight = panel_rect.mRight + (S32)(llround(panel_spacing)) + mResizeBarOverlap;
+
+ cur_pos += panel_visible_dim + panel_spacing;
+ }
+ else //VERTICAL
+ {
+ resize_bar_rect.mTop = panel_rect.mBottom + mResizeBarOverlap;
+ resize_bar_rect.mBottom = panel_rect.mBottom - (S32)(llround(panel_spacing)) - mResizeBarOverlap;
+
+ cur_pos -= panel_visible_dim + panel_spacing;
+ }
+ panelp->mResizeBar->setShape(resize_bar_rect);
+ }
+
+ updateResizeBarLimits();
+
+ // clear animation flag at end, since panel resizes will set it
+ // and leave it set if there is any animation in progress
+ mNeedsLayout = animation_in_progress;
+} // end LLLayoutStack::updateLayout
+
+LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const
{
- LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name);
+ if (!panelp) return NULL;
- if (panel)
+ e_panel_list_t::const_iterator panel_it;
+ BOOST_FOREACH(LLLayoutPanel* p, mPanels)
{
- panel->mUserResize = user_resize;
+ if (p == panelp)
+ {
+ return p;
+ }
}
+ return NULL;
}
-bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_dimp)
+LLLayoutPanel* LLLayoutStack::findEmbeddedPanelByName(const std::string& name) const
{
- LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name);
+ LLLayoutPanel* result = NULL;
- if (panel && min_dimp)
+ BOOST_FOREACH(LLLayoutPanel* p, mPanels)
{
- *min_dimp = panel->getRelevantMinDim();
+ if (p->getName() == name)
+ {
+ result = p;
+ break;
+ }
}
- return NULL != panel;
+ return result;
}
-bool LLLayoutStack::getPanelMaxSize(const std::string& panel_name, S32* max_dimp)
+void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp)
{
- LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name);
+ BOOST_FOREACH(LLLayoutPanel* lp, mPanels)
+ {
+ if (lp->mResizeBar == NULL)
+ {
+ LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
+ LLRect resize_bar_rect = getRect();
- if (panel)
+ LLResizeBar::Params resize_params;
+ resize_params.name("resize");
+ resize_params.resizing_view(lp);
+ resize_params.min_size(lp->getRelevantMinDim());
+ resize_params.side(side);
+ resize_params.snapping_enabled(false);
+ LLResizeBar* resize_bar = LLUICtrlFactory::create<LLResizeBar>(resize_params);
+ lp->mResizeBar = resize_bar;
+ LLView::addChild(resize_bar, 0);
+ }
+ }
+ // bring all resize bars to the front so that they are clickable even over the panels
+ // with a bit of overlap
+ for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
- if (max_dimp) *max_dimp = panel->mMaxDim;
+ LLResizeBar* resize_barp = (*panel_it)->mResizeBar;
+ sendChildToFront(resize_barp);
}
+}
- return NULL != panel;
+// update layout stack animations, etc. once per frame
+// NOTE: we use this to size world view based on animating UI, *before* we draw the UI
+// we might still need to call updateLayout during UI draw phase, in case UI elements
+// are resizing themselves dynamically
+//static
+void LLLayoutStack::updateClass()
+{
+ for (instance_iter it = beginInstances(); it != endInstances(); ++it)
+ {
+ it->updateLayout();
+ }
}
-static LLFastTimer::DeclareTimer FTM_UPDATE_LAYOUT("Update LayoutStacks");
-void LLLayoutStack::updateLayout(BOOL force_resize)
+void LLLayoutStack::updateFractionalSizes()
{
- LLFastTimer ft(FTM_UPDATE_LAYOUT);
- static LLUICachedControl<S32> resize_bar_overlap ("UIResizeBarOverlap", 0);
- calcMinExtents();
- createResizeBars();
+ F32 total_resizable_dim = 0;
+ S32 num_auto_resize_panels = 0;
- // calculate current extents
- F32 total_size = 0.f;
+ BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
+ {
+ if (panelp->mAutoResize)
+ {
+ total_resizable_dim += llmax(0, panelp->getLayoutDim() - panelp->getRelevantMinDim());
+ num_auto_resize_panels++;
+ }
+ }
+ F32 total_fractional_size = 0.f;
+
+ BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
+ {
+ if (panelp->mAutoResize)
+ {
+ F32 panel_resizable_dim = llmax(MIN_FRACTIONAL_SIZE, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim()));
+ panelp->mFractionalSize = panel_resizable_dim > 0.f
+ ? llclamp(panel_resizable_dim / total_resizable_dim, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE)
+ : MIN_FRACTIONAL_SIZE;
+ total_fractional_size += panelp->mFractionalSize;
+ llassert(!llisnan(panelp->mFractionalSize));
+ }
+ }
+
+ if (total_fractional_size == 0.f)
+ { // equal distribution
+ BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
+ {
+ if (panelp->mAutoResize)
+ {
+ panelp->mFractionalSize = MAX_FRACTIONAL_SIZE / (F32)num_auto_resize_panels;
+ }
+ }
+ }
+ else
+ { // renormalize
+ BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
+ {
+ if (panelp->mAutoResize)
+ {
+ panelp->mFractionalSize /= total_fractional_size;
+ }
+ }
+ }
+}
+
+bool LLLayoutStack::animatePanels()
+{
+ bool animation_in_progress = false;
+
//
// animate visibility
//
- e_panel_list_t::iterator panel_it;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
{
- LLLayoutPanel* panelp = (*panel_it);
- if (panelp->getVisible())
+ if (panelp->getVisible())
{
- if (mAnimate)
+ if (mAnimate && panelp->mVisibleAmt < 1.f)
{
if (!mAnimatedThisFrame)
{
@@ -345,15 +564,21 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
panelp->mVisibleAmt = 1.f;
}
}
+
+ animation_in_progress = true;
}
else
{
- panelp->mVisibleAmt = 1.f;
+ if (panelp->mVisibleAmt != 1.f)
+ {
+ panelp->mVisibleAmt = 1.f;
+ animation_in_progress = true;
+ }
}
}
else // not visible
{
- if (mAnimate)
+ if (mAnimate && panelp->mVisibleAmt > 0.f)
{
if (!mAnimatedThisFrame)
{
@@ -363,297 +588,213 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
panelp->mVisibleAmt = 0.f;
}
}
+
+ animation_in_progress = true;
}
else
{
- panelp->mVisibleAmt = 0.f;
+ if (panelp->mVisibleAmt != 0.f)
+ {
+ panelp->mVisibleAmt = 0.f;
+ animation_in_progress = true;
+ }
}
}
F32 collapse_state = panelp->mCollapsed ? 1.f : 0.f;
- panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
-
- total_size += panelp->mFractionalSize * panelp->getCollapseFactor();
- // want n-1 panel gaps for n panels
- if (panel_it != mPanels.begin())
- {
- total_size += mPanelSpacing;
- }
- }
-
- S32 num_resizable_panels = 0;
- F32 shrink_headroom_available = 0.f;
- F32 shrink_headroom_total = 0.f;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- LLLayoutPanel* panelp = (*panel_it);
-
- // panels that are not fully visible do not count towards shrink headroom
- if (panelp->getCollapseFactor() < 1.f)
- {
- continue;
- }
-
- F32 cur_size = panelp->mFractionalSize;
- F32 min_size = (F32)panelp->getRelevantMinDim();
-
- // if currently resizing a panel or the panel is flagged as not automatically resizing
- // only track total available headroom, but don't use it for automatic resize logic
- if (panelp->mResizeBar->hasMouseCapture()
- || (!panelp->mAutoResize
- && !force_resize))
- {
- shrink_headroom_total += cur_size - min_size;
- }
- else
- {
- num_resizable_panels++;
-
- shrink_headroom_available += cur_size - min_size;
- shrink_headroom_total += cur_size - min_size;
- }
- }
-
- // calculate how many pixels need to be distributed among layout panels
- // positive means panels need to grow, negative means shrink
- F32 pixels_to_distribute = (mOrientation == HORIZONTAL)
- ? getRect().getWidth() - total_size
- : getRect().getHeight() - total_size;
-
- // now we distribute the pixels...
- F32 cur_x = 0.f;
- F32 cur_y = (F32)getRect().getHeight();
-
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- LLLayoutPanel* panelp = (*panel_it);
-
- F32 min_size = panelp->getRelevantMinDim();
- F32 delta_size = 0.f;
-
- // if panel can automatically resize (not animating, and resize flag set)...
- if (panelp->getCollapseFactor() == 1.f
- && (force_resize || panelp->mAutoResize)
- && !panelp->mResizeBar->hasMouseCapture())
+ if (panelp->mCollapseAmt != collapse_state)
{
- if (pixels_to_distribute < 0.f)
+ if (!mAnimatedThisFrame)
{
- // shrink proportionally to amount over minimum
- // so we can do this in one pass
- delta_size = (shrink_headroom_available > 0.f)
- ? pixels_to_distribute * ((F32)(panelp->mFractionalSize - min_size) / shrink_headroom_available)
- : 0.f;
- shrink_headroom_available -= (panelp->mFractionalSize - min_size);
+ panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
}
- else
+ animation_in_progress = true;
+
+ if (llabs(panelp->mCollapseAmt - collapse_state) < 0.001f)
{
- // grow all elements equally
- delta_size = pixels_to_distribute / (F32)num_resizable_panels;
- num_resizable_panels--;
+ panelp->mCollapseAmt = collapse_state;
}
-
- panelp->mFractionalSize = llmax(min_size, panelp->mFractionalSize + delta_size);
- pixels_to_distribute -= delta_size;
}
+ }
- // adjust running headroom count based on new sizes
- shrink_headroom_total += delta_size;
+ mAnimatedThisFrame = true;
- LLRect panel_rect;
- if (mOrientation == HORIZONTAL)
- {
- panel_rect.setLeftTopAndSize(llround(cur_x),
- llround(cur_y),
- llround(panelp->mFractionalSize),
- getRect().getHeight());
- }
- else
- {
- panel_rect.setLeftTopAndSize(llround(cur_x),
- llround(cur_y),
- getRect().getWidth(),
- llround(panelp->mFractionalSize));
- }
- panelp->setShape(panel_rect);
+ return animation_in_progress;
+}
- LLRect resize_bar_rect = panel_rect;
- if (mOrientation == HORIZONTAL)
- {
- resize_bar_rect.mLeft = panel_rect.mRight - resize_bar_overlap;
- resize_bar_rect.mRight = panel_rect.mRight + mPanelSpacing + resize_bar_overlap;
- }
- else
- {
- resize_bar_rect.mTop = panel_rect.mBottom + resize_bar_overlap;
- resize_bar_rect.mBottom = panel_rect.mBottom - mPanelSpacing - resize_bar_overlap;
- }
- (*panel_it)->mResizeBar->setRect(resize_bar_rect);
+void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& new_rect )
+{
+ S32 new_dim = (mOrientation == HORIZONTAL)
+ ? new_rect.getWidth()
+ : new_rect.getHeight();
+ S32 delta_dim = new_dim - resized_panel->getVisibleDim();
+ if (delta_dim == 0) return;
- F32 size = ((*panel_it)->mFractionalSize * (*panel_it)->getCollapseFactor()) + (F32)mPanelSpacing;
- if (mOrientation == HORIZONTAL)
- {
- cur_x += size;
- }
- else //VERTICAL
- {
- cur_y -= size;
- }
- }
+ F32 total_visible_fraction = 0.f;
+ F32 delta_auto_resize_headroom = 0.f;
+ F32 total_auto_resize_headroom = 0.f;
- // update resize bars with new limits
- LLLayoutPanel* last_resizeable_panel = NULL;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- LLLayoutPanel* panelp = (*panel_it);
- S32 relevant_min = panelp->getRelevantMinDim();
+ LLLayoutPanel* other_resize_panel = NULL;
+ LLLayoutPanel* following_panel = NULL;
- if (mOrientation == HORIZONTAL)
+ BOOST_REVERSE_FOREACH(LLLayoutPanel* panelp, mPanels)
+ {
+ if (panelp->mAutoResize)
{
- (*panel_it)->mResizeBar->setResizeLimits(
- relevant_min,
- relevant_min + llround(shrink_headroom_total));
+ total_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim());
+ total_visible_fraction += panelp->mFractionalSize * panelp->getAutoResizeFactor();
}
- else //VERTICAL
+
+ if (panelp == resized_panel)
{
- (*panel_it)->mResizeBar->setResizeLimits(
- relevant_min,
- relevant_min + llround(shrink_headroom_total));
+ other_resize_panel = following_panel;
}
- // toggle resize bars based on panel visibility, resizability, etc
- BOOL resize_bar_enabled = panelp->getVisible() && (*panel_it)->mUserResize;
- (*panel_it)->mResizeBar->setVisible(resize_bar_enabled);
-
- if ((*panel_it)->mUserResize || (*panel_it)->mAutoResize)
+ if (panelp->getVisible() && !panelp->mCollapsed)
{
- last_resizeable_panel = (*panel_it);
+ following_panel = panelp;
}
}
- // hide last resize bar as there is nothing past it
- // resize bars need to be in between two resizable panels
- if (last_resizeable_panel)
+ if (resized_panel->mAutoResize == FALSE)
{
- last_resizeable_panel->mResizeBar->setVisible(FALSE);
+ delta_auto_resize_headroom += -delta_dim;
}
-
- // not enough room to fit existing contents
- if (force_resize == FALSE
- // layout did not complete by reaching target position
- && ((mOrientation == VERTICAL && llround(cur_y) != -mPanelSpacing)
- || (mOrientation == HORIZONTAL && llround(cur_x) != getRect().getWidth() + mPanelSpacing)))
+ if (other_resize_panel && other_resize_panel->mAutoResize == FALSE)
{
- // do another layout pass with all stacked elements contributing
- // even those that don't usually resize
- llassert_always(force_resize == FALSE);
- updateLayout(TRUE);
+ delta_auto_resize_headroom += delta_dim;
}
- mAnimatedThisFrame = true;
-} // end LLLayoutStack::updateLayout
+ F32 fraction_given_up = 0.f;
+ F32 fraction_remaining = 1.f;
+ F32 updated_auto_resize_headroom = total_auto_resize_headroom + delta_auto_resize_headroom;
-
-LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const
-{
- if (!panelp) return NULL;
-
- e_panel_list_t::const_iterator panel_it;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ enum
{
- if ((*panel_it) == panelp)
- {
- return *panel_it;
- }
- }
- return NULL;
-}
+ BEFORE_RESIZED_PANEL,
+ RESIZED_PANEL,
+ NEXT_PANEL,
+ AFTER_RESIZED_PANEL
+ } which_panel = BEFORE_RESIZED_PANEL;
-LLLayoutPanel* LLLayoutStack::findEmbeddedPanelByName(const std::string& name) const
-{
- LLLayoutPanel* result = NULL;
-
- for (e_panel_list_t::const_iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
{
- LLLayoutPanel* p = *panel_it;
+ if (!panelp->getVisible() || panelp->mCollapsed) continue;
- if (p->getName() == name)
+ if (panelp == resized_panel)
{
- result = p;
- break;
+ which_panel = RESIZED_PANEL;
}
- }
-
- return result;
-}
-
-// Compute sum of min_width or min_height of children
-void LLLayoutStack::calcMinExtents()
-{
- mMinWidth = 0;
- mMinHeight = 0;
- e_panel_list_t::iterator panel_it;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- if (mOrientation == HORIZONTAL)
+ switch(which_panel)
{
- mMinWidth += (*panel_it)->getRelevantMinDim();
- if (panel_it != mPanels.begin())
+ case BEFORE_RESIZED_PANEL:
+ if (panelp->mAutoResize)
+ { // freeze current size as fraction of overall auto_resize space
+ F32 fractional_adjustment_factor = total_auto_resize_headroom / updated_auto_resize_headroom;
+ F32 new_fractional_size = llclamp(panelp->mFractionalSize * fractional_adjustment_factor,
+ MIN_FRACTIONAL_SIZE,
+ MAX_FRACTIONAL_SIZE);
+ F32 fraction_delta = (new_fractional_size - panelp->mFractionalSize);
+ fraction_given_up -= fraction_delta;
+ fraction_remaining -= panelp->mFractionalSize;
+ panelp->mFractionalSize += fraction_delta;
+ llassert(!llisnan(panelp->mFractionalSize));
+ }
+ else
{
- mMinWidth += mPanelSpacing;
+ // leave non auto-resize panels alone
}
- }
- else //VERTICAL
- {
- mMinHeight += (*panel_it)->getRelevantMinDim();
- if (panel_it != mPanels.begin())
+ break;
+ case RESIZED_PANEL:
+ if (panelp->mAutoResize)
+ { // freeze new size as fraction
+ F32 new_fractional_size = (updated_auto_resize_headroom == 0.f)
+ ? MAX_FRACTIONAL_SIZE
+ : llclamp((F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
+ fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
+ fraction_remaining -= panelp->mFractionalSize;
+ panelp->mFractionalSize = new_fractional_size;
+ llassert(!llisnan(panelp->mFractionalSize));
+ }
+ else
+ { // freeze new size as original size
+ panelp->mTargetDim = new_dim;
+ fraction_remaining -= fraction_given_up;
+ }
+ which_panel = NEXT_PANEL;
+ break;
+ case NEXT_PANEL:
+ if (panelp->mAutoResize)
+ {
+ fraction_remaining -= panelp->mFractionalSize;
+ if (fraction_given_up != 0.f)
+ {
+ panelp->mFractionalSize = llclamp(panelp->mFractionalSize + fraction_given_up, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
+ fraction_given_up = 0.f;
+ }
+ else
+ {
+ F32 new_fractional_size = llclamp((F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom)
+ / updated_auto_resize_headroom,
+ MIN_FRACTIONAL_SIZE,
+ MAX_FRACTIONAL_SIZE);
+ fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
+ panelp->mFractionalSize = new_fractional_size;
+ }
+ }
+ else
+ {
+ panelp->mTargetDim -= delta_dim;
+ }
+ which_panel = AFTER_RESIZED_PANEL;
+ break;
+ case AFTER_RESIZED_PANEL:
+ if (panelp->mAutoResize)
{
- mMinHeight += mPanelSpacing;
+ panelp->mFractionalSize = llclamp(panelp->mFractionalSize + (panelp->mFractionalSize / fraction_remaining) * fraction_given_up,
+ MIN_FRACTIONAL_SIZE,
+ MAX_FRACTIONAL_SIZE);
}
+ default:
+ break;
}
}
}
-void LLLayoutStack::createResizeBars()
+void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent)
{
- for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ mNeedsLayout = true;
+ LLView::reshape(width, height, called_from_parent);
+}
+
+void LLLayoutStack::updateResizeBarLimits()
+{
+ LLLayoutPanel* previous_visible_panelp = NULL;
+ BOOST_REVERSE_FOREACH(LLLayoutPanel* visible_panelp, mPanels)
{
- LLLayoutPanel* lp = (*panel_it);
- if (lp->mResizeBar == NULL)
+ if (!visible_panelp->getVisible() || visible_panelp->mCollapsed)
{
- LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
- LLRect resize_bar_rect = getRect();
-
- LLResizeBar::Params resize_params;
- resize_params.name("resize");
- resize_params.resizing_view(lp);
- resize_params.min_size(lp->getRelevantMinDim());
- resize_params.side(side);
- resize_params.snapping_enabled(false);
- LLResizeBar* resize_bar = LLUICtrlFactory::create<LLResizeBar>(resize_params);
- lp->mResizeBar = resize_bar;
- LLView::addChild(resize_bar, 0);
+ visible_panelp->mResizeBar->setVisible(FALSE);
+ continue;
+ }
- // bring all resize bars to the front so that they are clickable even over the panels
- // with a bit of overlap
- for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- LLResizeBar* resize_barp = (*panel_it)->mResizeBar;
- sendChildToFront(resize_barp);
- }
+ // toggle resize bars based on panel visibility, resizability, etc
+ if (previous_visible_panelp
+ && (visible_panelp->mUserResize || previous_visible_panelp->mUserResize) // one of the pair is user resizable
+ && (visible_panelp->mAutoResize || visible_panelp->mUserResize) // current panel is resizable
+ && (previous_visible_panelp->mAutoResize || previous_visible_panelp->mUserResize)) // previous panel is resizable
+ {
+ visible_panelp->mResizeBar->setVisible(TRUE);
+ S32 previous_panel_headroom = previous_visible_panelp->getVisibleDim() - previous_visible_panelp->getRelevantMinDim();
+ visible_panelp->mResizeBar->setResizeLimits(visible_panelp->getRelevantMinDim(),
+ visible_panelp->getVisibleDim() + previous_panel_headroom);
+ }
+ else
+ {
+ visible_panelp->mResizeBar->setVisible(FALSE);
}
- }
-}
-// update layout stack animations, etc. once per frame
-// NOTE: we use this to size world view based on animating UI, *before* we draw the UI
-// we might still need to call updateLayout during UI draw phase, in case UI elements
-// are resizing themselves dynamically
-//static
-void LLLayoutStack::updateClass()
-{
- for (instance_iter it = beginInstances(); it != endInstances(); ++it)
- {
- it->updateLayout();
+ previous_visible_panelp = visible_panelp;
}
}
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index ede6149a80..efe93f6def 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2010, Linden Reshasearch, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -60,6 +60,7 @@ public:
clip;
Optional<F32> open_time_constant,
close_time_constant;
+ Optional<S32> resize_bar_overlap;
Params();
};
@@ -72,12 +73,11 @@ public:
/*virtual*/ void removeChild(LLView*);
/*virtual*/ BOOL postBuild();
/*virtual*/ bool addChild(LLView* child, S32 tab_group = 0);
+ /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);
- S32 getMinWidth() const { return mMinWidth; }
- S32 getMinHeight() const { return mMinHeight; }
-
typedef enum e_animate
{
NO_ANIMATE,
@@ -85,47 +85,24 @@ public:
} EAnimate;
void addPanel(LLLayoutPanel* panel, EAnimate animate = NO_ANIMATE);
- void removePanel(LLPanel* panel);
void collapsePanel(LLPanel* panel, BOOL collapsed = TRUE);
S32 getNumPanels() { return mPanels.size(); }
- /**
- * Moves panel_to_move before target_panel inside layout stack (both panels should already be there).
- * If move_to_front is true target_panel is ignored and panel_to_move is moved to the beginning of mPanels
- */
- void movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front = false);
-
- void updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize);
- void setPanelUserResize(const std::string& panel_name, BOOL user_resize);
-
- /**
- * Gets minimal dimension along layout_stack axis of the specified by name panel.
- *
- * @returns true if specified by panel_name internal panel exists, false otherwise.
- */
- bool getPanelMinSize(const std::string& panel_name, S32* min_dimp);
-
- /**
- * Gets maximal dimension along layout_stack axis of the specified by name panel.
- *
- * @returns true if specified by panel_name internal panel exists, false otherwise.
- */
- bool getPanelMaxSize(const std::string& panel_name, S32* max_dim);
-
- void updateLayout(BOOL force_resize = FALSE);
-
+
+ void updateLayout();
+
S32 getPanelSpacing() const { return mPanelSpacing; }
- BOOL getAnimate () const { return mAnimate; }
- void setAnimate (BOOL animate) { mAnimate = animate; }
static void updateClass();
protected:
LLLayoutStack(const Params&);
friend class LLUICtrlFactory;
+ friend class LLLayoutPanel;
private:
- void createResizeBars();
- void calcMinExtents();
+ void updateResizeBarLimits();
+ bool animatePanels();
+ void createResizeBar(LLLayoutPanel* panel);
const ELayoutOrientation mOrientation;
@@ -134,17 +111,19 @@ private:
LLLayoutPanel* findEmbeddedPanel(LLPanel* panelp) const;
LLLayoutPanel* findEmbeddedPanelByName(const std::string& name) const;
+ void updateFractionalSizes();
+ void updatePanelRect( LLLayoutPanel* param1, const LLRect& new_rect );
- S32 mMinWidth; // calculated by calcMinExtents
- S32 mMinHeight; // calculated by calcMinExtents
S32 mPanelSpacing;
// true if we already applied animation this frame
bool mAnimatedThisFrame;
bool mAnimate;
bool mClip;
- F32 mOpenTimeConstant;
- F32 mCloseTimeConstant;
+ F32 mOpenTimeConstant;
+ F32 mCloseTimeConstant;
+ bool mNeedsLayout;
+ S32 mResizeBarOverlap;
}; // end class LLLayoutStack
@@ -156,8 +135,7 @@ public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Optional<S32> expanded_min_dim,
- min_dim,
- max_dim;
+ min_dim;
Optional<bool> user_resize,
auto_resize;
@@ -168,16 +146,19 @@ public:
void initFromParams(const Params& p);
+ void handleReshape(const LLRect& new_rect, bool by_user);
+
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
- S32 getMinDim() const { return mMinDim; }
- void setMinDim(S32 value) { mMinDim = value; if (!mExpandedMinDimSpecified) mExpandedMinDim = value; }
+ void setVisible(BOOL visible);
- S32 getMaxDim() const { return mMaxDim; }
- void setMaxDim(S32 value) { mMaxDim = value; }
+ S32 getLayoutDim() const;
+ S32 getMinDim() const { return (mMinDim >= 0 || mAutoResize) ? llmax(0, mMinDim) : getLayoutDim(); }
+ void setMinDim(S32 value) { mMinDim = value; }
- S32 getExpandedMinDim() const { return mExpandedMinDim; }
- void setExpandedMinDim(S32 value) { mExpandedMinDim = value; mExpandedMinDimSpecified = true; }
+ S32 getExpandedMinDim() const { return mExpandedMinDim >= 0 ? mExpandedMinDim : mMinDim; }
+ void setExpandedMinDim(S32 value) { mExpandedMinDim = value; }
S32 getRelevantMinDim() const
{
@@ -185,30 +166,35 @@ public:
if (!mCollapsed)
{
- min_dim = mExpandedMinDim;
+ min_dim = getExpandedMinDim();
}
return min_dim;
}
- void setOrientation(LLLayoutStack::ELayoutOrientation orientation) { mOrientation = orientation; }
+ F32 getAutoResizeFactor() const;
+ F32 getVisibleAmount() const;
+ S32 getVisibleDim() const;
+
+ void setOrientation(LLLayoutStack::ELayoutOrientation orientation);
+ void storeOriginalDim();
+
+ void setIgnoreReshape(bool ignore) { mIgnoreReshape = ignore; }
protected:
LLLayoutPanel(const Params& p);
- F32 getCollapseFactor();
+ const bool mAutoResize;
+ const bool mUserResize;
- bool mExpandedMinDimSpecified;
S32 mExpandedMinDim;
-
S32 mMinDim;
- S32 mMaxDim;
- bool mAutoResize;
- bool mUserResize;
bool mCollapsed;
F32 mVisibleAmt;
F32 mCollapseAmt;
F32 mFractionalSize;
+ S32 mTargetDim;
+ bool mIgnoreReshape;
LLLayoutStack::ELayoutOrientation mOrientation;
class LLResizeBar* mResizeBar;
};
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index cb237fca7c..95ecbb1c94 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -947,9 +947,14 @@ LLMenuItemBranchGL::LLMenuItemBranchGL(const LLMenuItemBranchGL::Params& p)
LLMenuItemBranchGL::~LLMenuItemBranchGL()
{
- delete mBranchHandle.get();
+ if (mBranchHandle.get())
+ {
+ mBranchHandle.get()->die();
+ }
}
+
+
// virtual
LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse) const
{
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index cd33938226..f620201020 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -135,6 +135,8 @@ public:
const LLColor4& getBackgroundColor() const { return mBgOpaqueColor; }
void setTransparentColor(const LLColor4& color) { mBgAlphaColor = color; }
const LLColor4& getTransparentColor() const { return mBgAlphaColor; }
+ void setBackgroundImage(LLUIImage* image) { mBgOpaqueImage = image; }
+ void setTransparentImage(LLUIImage* image) { mBgAlphaImage = image; }
LLPointer<LLUIImage> getBackgroundImage() const { return mBgOpaqueImage; }
LLPointer<LLUIImage> getTransparentImage() const { return mBgAlphaImage; }
LLColor4 getBackgroundImageOverlay() { return mBgOpaqueImageOverlay; }
diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp
index 02f60c76fa..87aeb4d7a7 100644
--- a/indra/llui/llresizebar.cpp
+++ b/indra/llui/llresizebar.cpp
@@ -79,6 +79,8 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask)
{
+ if (!canResize()) return FALSE;
+
// Route future Mouse messages here preemptively. (Release on mouse up.)
// No handler needed for focus lost since this clas has no state that depends on it.
gFocusMgr.setMouseCapture( this );
@@ -243,7 +245,7 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
handled = TRUE;
}
- if( handled )
+ if( handled && canResize() )
{
switch( mSide )
{
diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h
index 0725fbd846..6daf191918 100644
--- a/indra/llui/llresizebar.h
+++ b/indra/llui/llresizebar.h
@@ -70,6 +70,7 @@ public:
void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; }
void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; }
void setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; }
+ bool canResize() { return getEnabled() && mMaxSize > mMinSize; }
private:
S32 mDragLastScreenX;
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index fe3f688fc5..ad4cc20d9a 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -424,63 +424,66 @@ void LLScrollContainer::draw()
focusFirstItem();
}
- // Draw background
- if( mIsOpaque )
+ if (getRect().isValid())
{
- F32 alpha = getCurrentTransparency();
+ // Draw background
+ if( mIsOpaque )
+ {
+ F32 alpha = getCurrentTransparency();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(mInnerRect, mBackgroundColor.get() % alpha);
- }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gl_rect_2d(mInnerRect, mBackgroundColor.get() % alpha);
+ }
- // Draw mScrolledViews and update scroll bars.
- // get a scissor region ready, and draw the scrolling view. The
- // scissor region ensures that we don't draw outside of the bounds
- // of the rectangle.
- if( mScrolledView )
- {
- updateScroll();
-
- // Draw the scrolled area.
+ // Draw mScrolledViews and update scroll bars.
+ // get a scissor region ready, and draw the scrolling view. The
+ // scissor region ensures that we don't draw outside of the bounds
+ // of the rectangle.
+ if( mScrolledView )
{
- S32 visible_width = 0;
- S32 visible_height = 0;
- BOOL show_v_scrollbar = FALSE;
- BOOL show_h_scrollbar = FALSE;
- calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
-
- LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
- mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height,
- mInnerRect.mRight - (show_v_scrollbar ? scrollbar_size: 0),
- mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0)
- ));
- drawChild(mScrolledView);
- }
- }
-
- // Highlight border if a child of this container has keyboard focus
- if( mBorder->getVisible() )
- {
- mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
- }
+ updateScroll();
- // Draw all children except mScrolledView
- // Note: scrollbars have been adjusted by above drawing code
- for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
- child_iter != getChildList()->rend(); ++child_iter)
- {
- LLView *viewp = *child_iter;
- if( sDebugRects )
- {
- sDepth++;
+ // Draw the scrolled area.
+ {
+ S32 visible_width = 0;
+ S32 visible_height = 0;
+ BOOL show_v_scrollbar = FALSE;
+ BOOL show_h_scrollbar = FALSE;
+ calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
+
+ LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
+ mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height,
+ mInnerRect.mRight - (show_v_scrollbar ? scrollbar_size: 0),
+ mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0)
+ ));
+ drawChild(mScrolledView);
+ }
}
- if( (viewp != mScrolledView) && viewp->getVisible() )
+
+ // Highlight border if a child of this container has keyboard focus
+ if( mBorder->getVisible() )
{
- drawChild(viewp);
+ mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
}
- if( sDebugRects )
+
+ // Draw all children except mScrolledView
+ // Note: scrollbars have been adjusted by above drawing code
+ for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
+ child_iter != getChildList()->rend(); ++child_iter)
{
- sDepth--;
+ LLView *viewp = *child_iter;
+ if( sDebugRects )
+ {
+ sDepth++;
+ }
+ if( (viewp != mScrolledView) && viewp->getVisible() )
+ {
+ drawChild(viewp);
+ }
+ if( sDebugRects )
+ {
+ sDepth--;
+ }
}
}
} // end draw
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index d5f8707381..5fc2cc350d 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -98,24 +98,25 @@ class LLCustomButtonIconCtrl : public LLButton
{
public:
struct Params
- : public LLInitParam::Block<Params, LLButton::Params>
+ : public LLInitParam::Block<Params, LLButton::Params>
{
// LEFT, RIGHT, TOP, BOTTOM paddings of LLIconCtrl in this class has same value
Optional<S32> icon_ctrl_pad;
- Params():
- icon_ctrl_pad("icon_ctrl_pad", 1)
+ Params()
+ : icon_ctrl_pad("icon_ctrl_pad", 1)
{}
};
protected:
friend class LLUICtrlFactory;
- LLCustomButtonIconCtrl(const Params& p):
- LLButton(p),
+
+ LLCustomButtonIconCtrl(const Params& p)
+ : LLButton(p),
mIcon(NULL),
mIconAlignment(LLFontGL::HCENTER),
mIconCtrlPad(p.icon_ctrl_pad)
- {}
+ {}
public:
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 3b768166f1..0040be45c7 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -598,7 +598,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
pos = getEditableIndex(pos, true);
- segment_set_t::iterator seg_iter = getSegIterContaining(pos);
+ segment_set_t::iterator seg_iter = getEditableSegIterContaining(pos);
LLTextSegmentPtr default_segment;
@@ -1510,8 +1510,48 @@ void LLTextBase::getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg
}
}
+LLTextBase::segment_set_t::iterator LLTextBase::getEditableSegIterContaining(S32 index)
+{
+ segment_set_t::iterator it = getSegIterContaining(index);
+ segment_set_t::iterator orig_it = it;
+
+ if (it == mSegments.end()) return it;
+
+ if (!(*it)->canEdit()
+ && index == (*it)->getStart()
+ && it != mSegments.begin())
+ {
+ it--;
+ if ((*it)->canEdit())
+ {
+ return it;
+ }
+ }
+ return orig_it;
+}
+
+LLTextBase::segment_set_t::const_iterator LLTextBase::getEditableSegIterContaining(S32 index) const
+{
+ segment_set_t::const_iterator it = getSegIterContaining(index);
+ segment_set_t::const_iterator orig_it = it;
+ if (it == mSegments.end()) return it;
+
+ if (!(*it)->canEdit()
+ && index == (*it)->getStart()
+ && it != mSegments.begin())
+ {
+ it--;
+ if ((*it)->canEdit())
+ {
+ return it;
+ }
+ }
+ return orig_it;
+}
+
LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index)
{
+
static LLPointer<LLIndexSegment> index_segment = new LLIndexSegment();
if (index > getLength()) { return mSegments.end(); }
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index b699601908..0549141b72 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -461,6 +461,8 @@ protected:
void getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const;
void getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp );
LLTextSegmentPtr getSegmentAtLocalPos( S32 x, S32 y, bool hit_past_end_of_line = true);
+ segment_set_t::iterator getEditableSegIterContaining(S32 index);
+ segment_set_t::const_iterator getEditableSegIterContaining(S32 index) const;
segment_set_t::iterator getSegIterContaining(S32 index);
segment_set_t::const_iterator getSegIterContaining(S32 index) const;
void clearSegments();
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 9bd445988d..3a23ce1cac 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2250,6 +2250,22 @@ void LLTextEditor::insertText(const std::string &new_text)
setEnabled( enabled );
}
+void LLTextEditor::insertText(LLWString &new_text)
+{
+ BOOL enabled = getEnabled();
+ setEnabled( TRUE );
+
+ // Delete any selected characters (the insertion replaces them)
+ if( hasSelection() )
+ {
+ deleteSelection(TRUE);
+ }
+
+ setCursorPos(mCursorPos + insert( mCursorPos, new_text, FALSE, LLTextSegmentPtr() ));
+
+ setEnabled( enabled );
+}
+
void LLTextEditor::appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo)
{
// Save old state
@@ -2838,3 +2854,13 @@ void LLTextEditor::clear()
getViewModel()->setDisplay(LLWStringUtil::null);
clearSegments();
}
+
+bool LLTextEditor::canLoadOrSaveToFile()
+{
+ return !mReadOnly;
+}
+
+S32 LLTextEditor::spacesPerTab()
+{
+ return SPACES_PER_TAB;
+}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 9e4b95003b..40821ae9fb 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -92,6 +92,8 @@ public:
void setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
+ static S32 spacesPerTab();
+
// mousehandler overrides
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@@ -140,6 +142,8 @@ public:
virtual void selectAll();
virtual BOOL canSelectAll() const;
+ virtual bool canLoadOrSaveToFile();
+
void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE);
BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE);
void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive);
@@ -158,6 +162,7 @@ public:
// inserts text at cursor
void insertText(const std::string &text);
+ void insertText(LLWString &text);
void appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo);
// Non-undoable
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 7f96c1373c..9b31a6449d 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -151,14 +151,20 @@ void LLToolBar::createContextMenu()
if (menu)
{
menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
-
mPopupMenuHandle = menu->getHandle();
+ mRemoveButtonHandle = menu->getChild<LLView>("Remove button")->getHandle();
}
else
{
llwarns << "Unable to load toolbars context menu." << llendl;
}
}
+
+ if (mRemoveButtonHandle.get())
+ {
+ // Disable/Enable the "Remove button" menu item depending on whether or not a button was clicked
+ mRemoveButtonHandle.get()->setEnabled(mRightMouseTargetButton != NULL);
+ }
}
void LLToolBar::initFromParams(const LLToolBar::Params& p)
@@ -401,6 +407,7 @@ BOOL LLToolBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
// Determine which button the mouse was over during the click in case the context menu action
// is intended to affect the button.
+ mRightMouseTargetButton = NULL;
BOOST_FOREACH(LLToolBarButton* button, mButtons)
{
LLRect button_rect;
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 51fe23ddd1..a50c60282c 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -271,6 +271,7 @@ private:
LLLayoutStack* mCenteringStack;
LLPanel* mButtonPanel;
LLHandle<class LLContextMenu> mPopupMenuHandle;
+ LLHandle<class LLView> mRemoveButtonHandle;
LLToolBarButton* mRightMouseTargetButton;
diff --git a/indra/llxuixml/lltrans.cpp b/indra/llui/lltrans.cpp
index 5388069c24..5388069c24 100644
--- a/indra/llxuixml/lltrans.cpp
+++ b/indra/llui/lltrans.cpp
diff --git a/indra/llxuixml/lltrans.h b/indra/llui/lltrans.h
index 128b51d383..128b51d383 100644
--- a/indra/llxuixml/lltrans.h
+++ b/indra/llui/lltrans.h
diff --git a/indra/llxuixml/lluicolor.cpp b/indra/llui/lluicolor.cpp
index f9bb80f8c5..f9bb80f8c5 100644
--- a/indra/llxuixml/lluicolor.cpp
+++ b/indra/llui/lluicolor.cpp
diff --git a/indra/llxuixml/lluicolor.h b/indra/llui/lluicolor.h
index 97ebea854a..97ebea854a 100644
--- a/indra/llxuixml/lluicolor.h
+++ b/indra/llui/lluicolor.h
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 486babb0ab..e1ee0a5b14 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -121,6 +121,7 @@ LLView::Params::Params()
LLView::LLView(const LLView::Params& p)
: mVisible(p.visible),
+ mInDraw(false),
mName(p.name),
mParentView(NULL),
mReshapeFlags(FOLLOWS_NONE),
@@ -333,6 +334,8 @@ void LLView::removeChild(LLView* child)
//llassert_always(sDepth == 0); // Avoid re-ordering while drawing; it can cause subtle iterator bugs
if (child->mParentView == this)
{
+ // if we are removing an item we are currently iterating over, that would be bad
+ llassert(child->mInDraw == false);
mChildList.remove( child );
child->mParentView = NULL;
if (child->isCtrl())
@@ -1090,6 +1093,11 @@ void LLView::drawChildren()
{
child_list_reverse_iter_t child = child_iter++;
LLView *viewp = *child;
+
+ if (viewp == NULL)
+ {
+ continue;
+ }
if (viewp->getVisible() && viewp->getRect().isValid())
{
@@ -1099,7 +1107,10 @@ void LLView::drawChildren()
LLUI::pushMatrix();
{
LLUI::translate((F32)viewp->getRect().mLeft, (F32)viewp->getRect().mBottom, 0.f);
+ // flag the fact we are in draw here, in case overridden draw() method attempts to remove this widget
+ viewp->mInDraw = true;
viewp->draw();
+ viewp->mInDraw = false;
if (sDebugRects)
{
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index f21fb37e18..f1fac5f69c 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -612,6 +612,8 @@ private:
S32 mNextInsertionOrdinal;
+ bool mInDraw;
+
static LLWindow* sWindow; // All root views must know about their window.
typedef std::map<std::string, LLView*> default_widget_map_t;
diff --git a/indra/llui/llwindowshade.cpp b/indra/llui/llwindowshade.cpp
index cf76202215..f5c463c961 100644
--- a/indra/llui/llwindowshade.cpp
+++ b/indra/llui/llwindowshade.cpp
@@ -37,10 +37,13 @@
const S32 MIN_NOTIFICATION_AREA_HEIGHT = 30;
const S32 MAX_NOTIFICATION_AREA_HEIGHT = 100;
+static LLDefaultChildRegistry::Register<LLWindowShade> r("window_shade");
+
LLWindowShade::Params::Params()
: bg_image("bg_image"),
modal("modal", false),
text_color("text_color"),
+ shade_color("shade_color"),
can_close("can_close", true)
{
changeDefault(mouse_opaque, false);
@@ -48,7 +51,6 @@ LLWindowShade::Params::Params()
LLWindowShade::LLWindowShade(const LLWindowShade::Params& params)
: LLUICtrl(params),
- mNotification(params.notification),
mModal(params.modal),
mFormHeight(0),
mTextColor(params.text_color)
@@ -72,7 +74,7 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
addChild(stackp);
LLLayoutPanel::Params panel_p;
- panel_p.rect = LLRect(0, 30, 800, 0);
+ panel_p.rect = LLRect(0, MIN_NOTIFICATION_AREA_HEIGHT, 800, 0);
panel_p.name = "notification_area";
panel_p.visible = false;
panel_p.user_resize = false;
@@ -89,7 +91,7 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
panel_p.name = "background_area";
panel_p.mouse_opaque = false;
panel_p.background_visible = false;
- panel_p.bg_alpha_color = LLColor4(0.f, 0.f, 0.f, 0.2f);
+ panel_p.bg_alpha_color = params.shade_color;
LLLayoutPanel* dummy_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
stackp->addChild(dummy_panel);
@@ -107,11 +109,11 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
LLIconCtrl::Params icon_p;
icon_p.name = "notification_icon";
- icon_p.rect = LLRect(5, 23, 21, 8);
+ icon_p.rect = LLRect(5, 25, 21, 10);
panel->addChild(LLUICtrlFactory::create<LLIconCtrl>(icon_p));
LLTextBox::Params text_p;
- text_p.rect = LLRect(31, 20, panel->getRect().getWidth() - 5, 0);
+ text_p.rect = LLRect(31, 23, panel->getRect().getWidth() - 5, 3);
text_p.follows.flags = FOLLOWS_ALL;
text_p.text_color = mTextColor;
text_p.font = LLFontGL::getFontSansSerifSmall();
@@ -125,41 +127,132 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
panel_p.auto_resize = false;
panel_p.user_resize = false;
panel_p.name="form_elements";
- panel_p.rect = LLRect(0, 30, 130, 0);
+ panel_p.rect = LLRect(0, MIN_NOTIFICATION_AREA_HEIGHT, 130, 0);
LLLayoutPanel* form_elements_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
stackp->addChild(form_elements_panel);
- if (params.can_close)
+ panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+ panel_p.auto_resize = false;
+ panel_p.user_resize = false;
+ panel_p.rect = LLRect(0, MIN_NOTIFICATION_AREA_HEIGHT, 25, 0);
+ panel_p.name = "close_panel";
+ LLLayoutPanel* close_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+ stackp->addChild(close_panel);
+
+ LLButton::Params button_p;
+ button_p.name = "close_notification";
+ button_p.rect = LLRect(5, 23, 21, 7);
+ button_p.image_color.control="DkGray_66";
+ button_p.image_unselected.name="Icon_Close_Foreground";
+ button_p.image_selected.name="Icon_Close_Press";
+ button_p.click_callback.function = boost::bind(&LLWindowShade::onCloseNotification, this);
+
+ close_panel->addChild(LLUICtrlFactory::create<LLButton>(button_p));
+
+ close_panel->setVisible(params.can_close);
+}
+
+void LLWindowShade::draw()
+{
+ LLRect message_rect = getChild<LLTextBox>("notification_text")->getTextBoundingRect();
+
+ LLLayoutPanel* notification_area = getChild<LLLayoutPanel>("notification_area");
+
+ notification_area->reshape(notification_area->getRect().getWidth(),
+ llclamp(message_rect.getHeight() + 15,
+ llmax(mFormHeight, MIN_NOTIFICATION_AREA_HEIGHT),
+ MAX_NOTIFICATION_AREA_HEIGHT));
+
+ LLUICtrl::draw();
+
+ while(!mNotifications.empty() && !mNotifications.back()->isActive())
+ {
+ mNotifications.pop_back();
+ // go ahead and hide
+ hide();
+ }
+
+ if (mNotifications.empty())
+ {
+ hide();
+ }
+ else if (notification_area->getVisibleAmount() < 0.01f)
+ {
+ displayLatestNotification();
+ }
+
+ if (!notification_area->getVisible() && (notification_area->getVisibleAmount() < 0.001f))
{
- panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
- panel_p.auto_resize = false;
- panel_p.user_resize = false;
- panel_p.rect = LLRect(0, 30, 25, 0);
- LLLayoutPanel* close_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
- stackp->addChild(close_panel);
-
- LLButton::Params button_p;
- button_p.name = "close_notification";
- button_p.rect = LLRect(5, 23, 21, 7);
- button_p.image_color.control="DkGray_66";
- button_p.image_unselected.name="Icon_Close_Foreground";
- button_p.image_selected.name="Icon_Close_Press";
- button_p.click_callback.function = boost::bind(&LLWindowShade::onCloseNotification, this);
-
- close_panel->addChild(LLUICtrlFactory::create<LLButton>(button_p));
+ getChildRef<LLLayoutPanel>("background_area").setBackgroundVisible(false);
+ setMouseOpaque(false);
}
+}
+
+void LLWindowShade::hide()
+{
+ getChildRef<LLLayoutPanel>("notification_area").setVisible(false);
+}
+
+void LLWindowShade::onCloseNotification()
+{
+ if (!mNotifications.empty())
+ LLNotifications::instance().cancel(mNotifications.back());
+}
+
+void LLWindowShade::onClickIgnore(LLUICtrl* ctrl)
+{
+ LLNotificationPtr notify = getCurrentNotification();
+ if (!notify) return;
+
+ bool check = ctrl->getValue().asBoolean();
+ if (notify->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
+ {
+ // question was "show again" so invert value to get "ignore"
+ check = !check;
+ }
+ notify->setIgnored(check);
+}
+
+void LLWindowShade::onClickNotificationButton(const std::string& name)
+{
+ LLNotificationPtr notify = getCurrentNotification();
+ if (!notify) return;
- LLSD payload = mNotification->getPayload();
+ mNotificationResponse[name] = true;
+
+ notify->respond(mNotificationResponse);
+}
- LLNotificationFormPtr formp = mNotification->getForm();
+void LLWindowShade::onEnterNotificationText(LLUICtrl* ctrl, const std::string& name)
+{
+ mNotificationResponse[name] = ctrl->getValue().asString();
+}
+
+void LLWindowShade::show(LLNotificationPtr notification)
+{
+ mNotifications.push_back(notification);
+
+ displayLatestNotification();
+}
+
+void LLWindowShade::displayLatestNotification()
+{
+ if (mNotifications.empty()) return;
+
+ LLNotificationPtr notification = mNotifications.back();
+
+ LLSD payload = notification->getPayload();
+
+ LLNotificationFormPtr formp = notification->getForm();
LLLayoutPanel& notification_area = getChildRef<LLLayoutPanel>("notification_area");
- notification_area.getChild<LLUICtrl>("notification_icon")->setValue(mNotification->getIcon());
- notification_area.getChild<LLUICtrl>("notification_text")->setValue(mNotification->getMessage());
- notification_area.getChild<LLUICtrl>("notification_text")->setToolTip(mNotification->getMessage());
+ notification_area.getChild<LLUICtrl>("notification_icon")->setValue(notification->getIcon());
+ notification_area.getChild<LLUICtrl>("notification_text")->setValue(notification->getMessage());
+ notification_area.getChild<LLUICtrl>("notification_text")->setToolTip(notification->getMessage());
LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType();
LLLayoutPanel& form_elements = notification_area.getChildRef<LLLayoutPanel>("form_elements");
form_elements.deleteAllChildren();
+ form_elements.reshape(form_elements.getRect().getWidth(), MIN_NOTIFICATION_AREA_HEIGHT);
const S32 FORM_PADDING_HORIZONTAL = 10;
const S32 FORM_PADDING_VERTICAL = 3;
@@ -229,7 +322,7 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
label_p.v_pad = 5;
LLTextBox* textbox = LLUICtrlFactory::create<LLTextBox>(label_p);
textbox->reshapeToFitText();
- textbox->reshape(textbox->getRect().getWidth(), form_elements.getRect().getHeight() - 2 * FORM_PADDING_VERTICAL);
+ textbox->reshape(textbox->getRect().getWidth(), MIN_NOTIFICATION_AREA_HEIGHT - 2 * FORM_PADDING_VERTICAL);
form_elements.addChild(textbox);
cur_x = textbox->getRect().mRight + FORM_PADDING_HORIZONTAL;
@@ -249,7 +342,7 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
}
}
- mFormHeight = form_elements.getRect().getHeight() - (cur_y - FORM_PADDING_VERTICAL) + WIDGET_HEIGHT;
+ mFormHeight = form_elements.getRect().getHeight() - (cur_y - WIDGET_HEIGHT - FORM_PADDING_VERTICAL);
form_elements.reshape(form_width, mFormHeight);
form_elements.setMinDim(form_width);
@@ -261,68 +354,39 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
{
(*it)->translate(0, delta_y);
}
-}
-void LLWindowShade::show()
-{
getChildRef<LLLayoutPanel>("notification_area").setVisible(true);
getChildRef<LLLayoutPanel>("background_area").setBackgroundVisible(mModal);
setMouseOpaque(mModal);
}
-void LLWindowShade::draw()
+void LLWindowShade::setBackgroundImage(LLUIImage* image)
{
- LLRect message_rect = getChild<LLTextBox>("notification_text")->getTextBoundingRect();
-
- LLLayoutPanel* notification_area = getChild<LLLayoutPanel>("notification_area");
-
- notification_area->reshape(notification_area->getRect().getWidth(),
- llclamp(message_rect.getHeight() + 10,
- llmin(mFormHeight, MAX_NOTIFICATION_AREA_HEIGHT),
- MAX_NOTIFICATION_AREA_HEIGHT));
-
- LLUICtrl::draw();
- if (mNotification && !mNotification->isActive())
- {
- hide();
- }
+ getChild<LLLayoutPanel>("notification_area")->setTransparentImage(image);
}
-void LLWindowShade::hide()
+void LLWindowShade::setTextColor(LLColor4 color)
{
- getChildRef<LLLayoutPanel>("notification_area").setVisible(false);
- getChildRef<LLLayoutPanel>("background_area").setBackgroundVisible(false);
-
- setMouseOpaque(false);
+ getChild<LLTextBox>("notification_text")->setColor(color);
}
-void LLWindowShade::onCloseNotification()
+bool LLWindowShade::isShown() const
{
- LLNotifications::instance().cancel(mNotification);
+ return getChildRef<LLLayoutPanel>("notification_area").getVisible();
}
-void LLWindowShade::onClickIgnore(LLUICtrl* ctrl)
+void LLWindowShade::setCanClose(bool can_close)
{
- bool check = ctrl->getValue().asBoolean();
- if (mNotification && mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
- {
- // question was "show again" so invert value to get "ignore"
- check = !check;
- }
- mNotification->setIgnored(check);
+ getChildView("close_panel")->setVisible(can_close);
}
-void LLWindowShade::onClickNotificationButton(const std::string& name)
+LLNotificationPtr LLWindowShade::getCurrentNotification()
{
- if (!mNotification) return;
-
- mNotificationResponse[name] = true;
-
- mNotification->respond(mNotificationResponse);
+ if (mNotifications.empty())
+ {
+ return LLNotificationPtr();
+ }
+ return mNotifications.back();
}
-void LLWindowShade::onEnterNotificationText(LLUICtrl* ctrl, const std::string& name)
-{
- mNotificationResponse[name] = ctrl->getValue().asString();
-}
diff --git a/indra/llui/llwindowshade.h b/indra/llui/llwindowshade.h
index 09ffc2cd54..6d753d1161 100644
--- a/indra/llui/llwindowshade.h
+++ b/indra/llui/llwindowshade.h
@@ -36,20 +36,28 @@ class LLWindowShade : public LLUICtrl
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
- Mandatory<LLNotificationPtr> notification;
Optional<LLUIImage*> bg_image;
- Optional<LLUIColor> text_color;
+ Optional<LLUIColor> text_color,
+ shade_color;
Optional<bool> modal,
can_close;
Params();
};
- void show();
+ void show(LLNotificationPtr);
/*virtual*/ void draw();
void hide();
+
+ bool isShown() const;
+
+ void setBackgroundImage(LLUIImage* image);
+ void setTextColor(LLColor4 color);
+ void setCanClose(bool can_close);
private:
+ void displayLatestNotification();
+ LLNotificationPtr getCurrentNotification();
friend class LLUICtrlFactory;
LLWindowShade(const Params& p);
@@ -60,7 +68,7 @@ private:
void onEnterNotificationText(LLUICtrl* ctrl, const std::string& name);
void onClickIgnore(LLUICtrl* ctrl);
- LLNotificationPtr mNotification;
+ std::vector<LLNotificationPtr> mNotifications;
LLSD mNotificationResponse;
bool mModal;
S32 mFormHeight;
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index afc76024d1..afc76024d1 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llui/llxuiparser.h
index d7cd256967..d7cd256967 100644
--- a/indra/llxuixml/llxuiparser.h
+++ b/indra/llui/llxuiparser.h
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index c75df86891..cb3b7abb14 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -105,28 +105,6 @@ LLStyle::Params::Params()
namespace LLInitParam
{
- Param::Param(BaseBlock* enclosing_block)
- : mIsProvided(false)
- {
- const U8* my_addr = reinterpret_cast<const U8*>(this);
- const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
- mEnclosingBlockOffset = (U16)(my_addr - block_addr);
- }
-
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
- void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
- param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
-
- void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
- {
- descriptor.mCurrentBlockPtr = this;
- }
- bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; }
- void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const {}
- bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_value, S32 max_value) const { return true; }
- bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
- bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
-
ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
: super_t(color)
{}
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index c1fb050206..8f0a48018f 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -70,21 +70,6 @@ S32 LLUIImage::getHeight() const
return 0;
}
-namespace LLInitParam
-{
- BlockDescriptor::BlockDescriptor() {}
- ParamDescriptor::ParamDescriptor(param_handle_t p,
- merge_func_t merge_func,
- deserialize_func_t deserialize_func,
- serialize_func_t serialize_func,
- validation_func_t validation_func,
- inspect_func_t inspect_func,
- S32 min_count,
- S32 max_count){}
- ParamDescriptor::~ParamDescriptor() {}
-
-}
-
namespace tut
{
struct LLUrlEntryData
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 7183413463..963473c92a 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -63,40 +63,6 @@ S32 LLUIImage::getHeight() const
namespace LLInitParam
{
- BlockDescriptor::BlockDescriptor() {}
- ParamDescriptor::ParamDescriptor(param_handle_t p,
- merge_func_t merge_func,
- deserialize_func_t deserialize_func,
- serialize_func_t serialize_func,
- validation_func_t validation_func,
- inspect_func_t inspect_func,
- S32 min_count,
- S32 max_count){}
- ParamDescriptor::~ParamDescriptor() {}
-
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
- param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
- void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
-
- void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
- {
- descriptor.mCurrentBlockPtr = this;
- }
-
- Param::Param(BaseBlock* enclosing_block)
- : mIsProvided(false)
- {
- const U8* my_addr = reinterpret_cast<const U8*>(this);
- const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
- mEnclosingBlockOffset = 0x7FFFffff & ((U32)(my_addr - block_addr));
- }
-
- bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; }
- void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const {}
- bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const { return true; }
- bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
- bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
-
ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
: super_t(color)
{}
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index 1351bed547..2e9e31bfea 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -186,8 +186,8 @@ BOOL LLWindow::setSize(LLCoordScreen size)
{
if (!getMaximized())
{
- size.mX = llmin(size.mX, mMinWindowWidth);
- size.mY = llmin(size.mY, mMinWindowHeight);
+ size.mX = llmax(size.mX, mMinWindowWidth);
+ size.mY = llmax(size.mY, mMinWindowHeight);
}
return setSizeImpl(size);
}
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 52c27b6736..228fbefd19 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -1083,6 +1083,37 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
return FALSE;
}
+ // (EXP-1765) dump pixel data to see if there is a pattern that leads to unreproducible crash
+ LL_INFOS("Window") << "--- begin pixel format dump ---" << llendl ;
+ LL_INFOS("Window") << "pixel_format is " << pixel_format << llendl ;
+ LL_INFOS("Window") << "pfd.nSize: " << pfd.nSize << llendl ;
+ LL_INFOS("Window") << "pfd.nVersion: " << pfd.nVersion << llendl ;
+ LL_INFOS("Window") << "pfd.dwFlags: 0x" << std::hex << pfd.dwFlags << std::dec << llendl ;
+ LL_INFOS("Window") << "pfd.iPixelType: " << (int)pfd.iPixelType << llendl ;
+ LL_INFOS("Window") << "pfd.cColorBits: " << (int)pfd.cColorBits << llendl ;
+ LL_INFOS("Window") << "pfd.cRedBits: " << (int)pfd.cRedBits << llendl ;
+ LL_INFOS("Window") << "pfd.cRedShift: " << (int)pfd.cRedShift << llendl ;
+ LL_INFOS("Window") << "pfd.cGreenBits: " << (int)pfd.cGreenBits << llendl ;
+ LL_INFOS("Window") << "pfd.cGreenShift: " << (int)pfd.cGreenShift << llendl ;
+ LL_INFOS("Window") << "pfd.cBlueBits: " << (int)pfd.cBlueBits << llendl ;
+ LL_INFOS("Window") << "pfd.cBlueShift: " << (int)pfd.cBlueShift << llendl ;
+ LL_INFOS("Window") << "pfd.cAlphaBits: " << (int)pfd.cAlphaBits << llendl ;
+ LL_INFOS("Window") << "pfd.cAlphaShift: " << (int)pfd.cAlphaShift << llendl ;
+ LL_INFOS("Window") << "pfd.cAccumBits: " << (int)pfd.cAccumBits << llendl ;
+ LL_INFOS("Window") << "pfd.cAccumRedBits: " << (int)pfd.cAccumRedBits << llendl ;
+ LL_INFOS("Window") << "pfd.cAccumGreenBits: " << (int)pfd.cAccumGreenBits << llendl ;
+ LL_INFOS("Window") << "pfd.cAccumBlueBits: " << (int)pfd.cAccumBlueBits << llendl ;
+ LL_INFOS("Window") << "pfd.cAccumAlphaBits: " << (int)pfd.cAccumAlphaBits << llendl ;
+ LL_INFOS("Window") << "pfd.cDepthBits: " << (int)pfd.cDepthBits << llendl ;
+ LL_INFOS("Window") << "pfd.cStencilBits: " << (int)pfd.cStencilBits << llendl ;
+ LL_INFOS("Window") << "pfd.cAuxBuffers: " << (int)pfd.cAuxBuffers << llendl ;
+ LL_INFOS("Window") << "pfd.iLayerType: " << (int)pfd.iLayerType << llendl ;
+ LL_INFOS("Window") << "pfd.bReserved: " << (int)pfd.bReserved << llendl ;
+ LL_INFOS("Window") << "pfd.dwLayerMask: " << pfd.dwLayerMask << llendl ;
+ LL_INFOS("Window") << "pfd.dwVisibleMask: " << pfd.dwVisibleMask << llendl ;
+ LL_INFOS("Window") << "pfd.dwDamageMask: " << pfd.dwDamageMask << llendl ;
+ LL_INFOS("Window") << "--- end pixel format dump ---" << llendl ;
+
if (pfd.cColorBits < 32)
{
close();
@@ -1716,7 +1747,7 @@ void LLWindowWin32::gatherInput()
LLMemType m1(LLMemType::MTYPE_GATHER_INPUT);
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) && msg_count < MAX_MESSAGE_PER_UPDATE)
+ while ((msg_count < MAX_MESSAGE_PER_UPDATE) && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
mCallbacks->handlePingWatchdog(this, "Main:TranslateGatherInput");
TranslateMessage(&msg);
diff --git a/indra/llxuixml/CMakeLists.txt b/indra/llxuixml/CMakeLists.txt
deleted file mode 100644
index daed4de6ce..0000000000
--- a/indra/llxuixml/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-# -*- cmake -*-
-
-project(llxuixml)
-
-include(00-Common)
-include(LLCommon)
-include(LLMath)
-include(LLXML)
-
-include_directories(
- ${LLCOMMON_INCLUDE_DIRS}
- ${LLMATH_INCLUDE_DIRS}
- ${LLXML_INCLUDE_DIRS}
- )
-
-set(llxuixml_SOURCE_FILES
- llinitparam.cpp
- lltrans.cpp
- lluicolor.cpp
- llxuiparser.cpp
- )
-
-set(llxuixml_HEADER_FILES
- CMakeLists.txt
-
- llinitparam.h
- lltrans.h
- llregistry.h
- lluicolor.h
- llxuiparser.h
- )
-
-set_source_files_properties(${llxuixml_HEADER_FILES}
- PROPERTIES HEADER_FILE_ONLY TRUE)
-
-list(APPEND llxuixml_SOURCE_FILES ${llxuixml_HEADER_FILES})
-
-add_library (llxuixml ${llxuixml_SOURCE_FILES})
-# Libraries on which this library depends, needed for Linux builds
-# Sort by high-level to low-level
-target_link_libraries(llxuixml
- llxml
- llcommon
- llmath
- )
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6b2fe1e45a..61ece1f857 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -30,7 +30,6 @@ include(LLUI)
include(LLVFS)
include(LLWindow)
include(LLXML)
-include(LLXUIXML)
include(LScript)
include(Linking)
include(NDOF)
@@ -65,7 +64,6 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
- ${LLXUIXML_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}/lscript_compile
${LLLOGIN_INCLUDE_DIRS}
@@ -216,6 +214,7 @@ set(viewer_SOURCE_FILES
llfloaternotificationsconsole.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
+ llfloateroutbox.cpp
llfloaterpay.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
@@ -314,6 +313,8 @@ set(viewer_SOURCE_FILES
llmaniprotate.cpp
llmanipscale.cpp
llmaniptranslate.cpp
+ llmarketplacefunctions.cpp
+ llmarketplacenotifications.cpp
llmediactrl.cpp
llmediadataclient.cpp
llmemoryview.cpp
@@ -370,7 +371,6 @@ set(viewer_SOURCE_FILES
llpanelmaininventory.cpp
llpanelmarketplaceinbox.cpp
llpanelmarketplaceinboxinventory.cpp
- llpanelmarketplaceoutbox.cpp
llpanelmarketplaceoutboxinventory.cpp
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
@@ -770,6 +770,7 @@ set(viewer_HEADER_FILES
llfloaternotificationsconsole.h
llfloaterobjectweights.h
llfloateropenobject.h
+ llfloateroutbox.h
llfloaterpay.h
llfloaterperms.h
llfloaterpostprocess.h
@@ -868,6 +869,8 @@ set(viewer_HEADER_FILES
llmaniprotate.h
llmanipscale.h
llmaniptranslate.h
+ llmarketplacefunctions.h
+ llmarketplacenotifications.h
llmediactrl.h
llmediadataclient.h
llmemoryview.h
@@ -918,7 +921,6 @@ set(viewer_HEADER_FILES
llpanelmaininventory.h
llpanelmarketplaceinbox.h
llpanelmarketplaceinboxinventory.h
- llpanelmarketplaceoutbox.h
llpanelmarketplaceoutboxinventory.h
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
@@ -1740,7 +1742,6 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLVFS_LIBRARIES}
${LLWINDOW_LIBRARIES}
${LLXML_LIBRARIES}
- ${LLXUIXML_LIBRARIES}
${LSCRIPT_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index a44b895f7b..1d1d39c786 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -135,6 +135,16 @@
is_running_function="Floater.IsOpen"
is_running_parameters="moveview"
/>
+ <command name="outbox"
+ available_in_toybox="false"
+ icon="Command_Outbox_Icon"
+ label_ref="Command_Outbox_Label"
+ tooltip_ref="Command_Outbox_Tooltip"
+ execute_function="Floater.ToggleOrBringToFront"
+ execute_parameters="outbox"
+ is_running_function="Floater.IsOpen"
+ is_running_parameters="outbox"
+ />
<command name="people"
available_in_toybox="true"
icon="Command_People_Icon"
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index aa8ad53a3d..0e26013152 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1150,6 +1150,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>EnableButtonFlashing</key>
+ <map>
+ <key>Comment</key>
+ <string>Allow UI to flash buttons to get your attention</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>ButtonHPad</key>
<map>
<key>Comment</key>
@@ -1817,6 +1828,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>CurlMaximumNumberOfHandles</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum number of handles curl can use (requires restart)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>256</integer>
+ </map>
+ <key>CurlRequestTimeOut</key>
+ <map>
+ <key>Comment</key>
+ <string>Max idle time of a curl request before killed (requires restart)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>120.0</real>
+ </map>
<key>CurlUseMultipleThreads</key>
<map>
<key>Comment</key>
@@ -4260,16 +4293,49 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>InventoryMarketplaceUserStatus</key>
+ <key>InventoryOutboxLogging</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable debug output associated with the Merchant Outbox.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>InventoryOutboxMaxFolderCount</key>
<map>
<key>Comment</key>
- <string>Marketplace user status.</string>
+ <string>Maximum number of subfolders allowed in a listing in the merchant outbox.</string>
<key>Persist</key>
- <integer>1</integer>
+ <integer>0</integer>
<key>Type</key>
- <string>String</string>
+ <string>U32</string>
<key>Value</key>
- <string />
+ <integer>21</integer>
+ </map>
+ <key>InventoryOutboxMaxFolderDepth</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum number of nested levels of subfolders allowed in a listing in the merchant outbox.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>4</integer>
+ </map>
+ <key>InventoryOutboxMaxItemCount</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum number of items allowed in a listing in the merchant outbox.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>200</integer>
</map>
<key>InventorySortOrder</key>
<map>
@@ -9013,6 +9079,28 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderAutoMuteByteLimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum bytes of attachments before an avatar is automatically visually muted (0 for no limit).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderAutoMuteSurfaceAreaLimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum surface area of attachments before an avatar is automatically visually muted (0 for no limit).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderUseShaderLOD</key>
<map>
<key>Comment</key>
@@ -11334,17 +11422,6 @@
<key>Value</key>
<real>3</real>
</map>
- <key>UIResizeBarOverlap</key>
- <map>
- <key>Comment</key>
- <string>Size of UI resize bar overlap</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <real>1</real>
- </map>
<key>UIScaleFactor</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
index b09441f7eb..40b0cf47ac 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
@@ -30,7 +30,6 @@ ATTRIBUTE vec3 normal;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
mat4 getObjectSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
@@ -38,8 +37,6 @@ float calcDirectionalLight(vec3 n, vec3 l);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
VARYING vec3 vary_position;
VARYING vec3 vary_ambient;
@@ -64,17 +61,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
vec3 lv = lp.xyz-v;
//get distance
- float d = length(lv);
+ float d = dot(lv,lv);
float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
//normalize light vector
- lv *= 1.0/d;
+ lv = normalize(lv);
//distance attenuation
- float dist2 = d*d/(la*la);
+ float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient.
@@ -82,7 +79,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation
- da *= calcDirectionalLight(n, lv);
+ da *= max(dot(n, lv), 0.0);
}
return da;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
index 93b1a114db..8c96d55342 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
@@ -70,17 +70,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
vec3 lv = lp.xyz-v;
//get distance
- float d = length(lv);
+ float d = dot(lv,lv);
float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
//normalize light vector
- lv *= 1.0/d;
+ lv = normalize(lv);
//distance attenuation
- float dist2 = d*d/(la*la);
+ float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient.
@@ -88,7 +88,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation
- da *= calcDirectionalLight(n, lv);
+ da *= max(dot(n, lv), 0.0);
}
return da;
@@ -123,7 +123,6 @@ void main()
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
vary_pointlight_col = col.rgb*diffuse_color.rgb;
-
col.rgb = vec3(0,0,0);
// Add windlight lights
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
index d7b90978ba..c0edddc40a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
@@ -65,17 +65,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
vec3 lv = lp.xyz-v;
//get distance
- float d = length(lv);
+ float d = dot(lv,lv);
float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
//normalize light vector
- lv *= 1.0/d;
+ lv = normalize(lv);
//distance attenuation
- float dist2 = d*d/(la*la);
+ float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient.
@@ -83,7 +83,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation
- da *= calcDirectionalLight(n, lv);
+ da *= max(dot(n, lv), 0.0);
}
return da;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
index 88fe3c3dee..e612efba61 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
@@ -57,7 +57,7 @@ float getDepth(vec2 pos_screen)
float calc_cof(float depth)
{
- float sc = abs(depth-focal_distance)/-depth*blur_constant;
+ float sc = (depth-focal_distance)/-depth*blur_constant;
sc /= magnification;
@@ -79,9 +79,10 @@ void main()
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
float sc = calc_cof(depth);
- sc = min(abs(sc), max_cof);
+ sc = min(sc, max_cof);
+ sc = max(sc, -max_cof);
vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
gl_FragColor.rgb = diff.rgb + bloom.rgb;
- gl_FragColor.a = sc/max_cof;
+ gl_FragColor.a = sc/max_cof*0.5+0.5;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
index 21453aefaa..01e3505359 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
@@ -48,7 +48,7 @@ void main()
vec4 diff = texture2DRect(lightMap, vary_fragcoord.xy);
- float a = min(diff.a * max_cof*res_scale*res_scale, 1.0);
+ float a = min(abs(diff.a*2.0-1.0) * max_cof*res_scale*res_scale, 1.0);
if (a > 0.25 && a < 0.75)
{ //help out the transition a bit
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
index 4603d99c5e..18d451bf87 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
@@ -42,7 +42,7 @@ void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc)
{
vec4 s = texture2DRect(diffuseRect, tc);
- float sc = s.a*max_cof;
+ float sc = abs(s.a*2.0-1.0)*max_cof;
if (sc > min_sc) //sampled pixel is more "out of focus" than current sample radius
{
@@ -57,6 +57,20 @@ void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc)
}
}
+void dofSampleNear(inout vec4 diff, inout float w, float min_sc, vec2 tc)
+{
+ vec4 s = texture2DRect(diffuseRect, tc);
+
+ float wg = 0.25;
+
+ // de-weight dull areas to make highlights 'pop'
+ wg += s.r+s.g+s.b;
+
+ diff += wg*s;
+
+ w += wg;
+}
+
void main()
{
vec2 tc = vary_fragcoord.xy;
@@ -66,12 +80,30 @@ void main()
{
float w = 1.0;
- float sc = diff.a*max_cof;
-
+ float sc = (diff.a*2.0-1.0)*max_cof;
+
float PI = 3.14159265358979323846264;
// sample quite uniformly spaced points within a circle, for a circular 'bokeh'
+ if (sc > 0.5)
+ {
+ while (sc > 0.5)
+ {
+ int its = int(max(1.0,(sc*3.7)));
+ for (int i=0; i<its; ++i)
+ {
+ float ang = sc+i*2*PI/its; // sc is added for rotary perturbance
+ float samp_x = sc*sin(ang);
+ float samp_y = sc*cos(ang);
+ // you could test sample coords against an interesting non-circular aperture shape here, if desired.
+ dofSampleNear(diff, w, sc, vary_fragcoord.xy + vec2(samp_x,samp_y));
+ }
+ sc -= 1.0;
+ }
+ }
+ else if (sc < -0.5)
{
+ sc = abs(sc);
while (sc > 0.5)
{
int its = int(max(1.0,(sc*3.7)));
@@ -86,7 +118,7 @@ void main()
sc -= 1.0;
}
}
-
+
diff /= w;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
index 5a3955ef00..83815b1786 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
@@ -63,21 +63,21 @@ uniform vec3 light_diffuse[8];
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{
- //get light vector
+//get light vector
vec3 lv = lp.xyz-v;
//get distance
- float d = length(lv);
+ float d = dot(lv,lv);
float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
//normalize light vector
- lv *= 1.0/d;
+ lv = normalize(lv);
//distance attenuation
- float dist2 = d*d/(la*la);
+ float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient.
@@ -85,7 +85,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation
- da *= calcDirectionalLight(n, lv);
+ da *= max(dot(n, lv), 0.0);
}
return da;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
index 9540ddd2e8..1660f9687e 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
@@ -69,17 +69,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
vec3 lv = lp.xyz-v;
//get distance
- float d = length(lv);
+ float d = dot(lv,lv);
float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
//normalize light vector
- lv *= 1.0/d;
+ lv = normalize(lv);
//distance attenuation
- float dist2 = d*d/(la*la);
+ float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient.
@@ -87,7 +87,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation
- da *= calcDirectionalLight(n, lv);
+ da *= max(dot(n, lv), 0.0);
}
return da;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
index 9c7a332417..84c27edb26 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
@@ -66,17 +66,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
vec3 lv = lp.xyz-v;
//get distance
- float d = length(lv);
+ float d = dot(lv,lv);
float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
//normalize light vector
- lv *= 1.0/d;
+ lv = normalize(lv);
//distance attenuation
- float dist2 = d*d/(la*la);
+ float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient.
@@ -84,7 +84,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation
- da *= calcDirectionalLight(n, lv);
+ da *= max(dot(n, lv), 0.0);
}
return da;
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 54ad3cd187..ab9b5ff436 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3314,6 +3314,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
}
llinfos << "Received cached texture response for " << num_results << " textures." << llendl;
+ gAgentAvatarp->outputRezTiming("Fetched agent wearables textures from cache. Will now load them");
gAgentAvatarp->updateMeshTextures();
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 13b62cb019..09305a5b4d 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -185,6 +185,7 @@ void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
{
if (avatar)
{
+ avatar->outputRezTiming("Sending wearables request");
sendAgentWearablesRequest();
}
}
@@ -949,6 +950,11 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
if (mInitialWearablesUpdateReceived)
return;
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->outputRezTiming("Received initial wearables update");
+ }
+
// notify subscribers that wearables started loading. See EXT-7777
// *TODO: find more proper place to not be called from deprecated method.
// Seems such place is found: LLInitialWearablesFetch::processContents()
@@ -1619,6 +1625,11 @@ void LLAgentWearables::queryWearableCache()
//VWR-22113: gAgent.getRegion() can return null if invalid, seen here on logout
if(gAgent.getRegion())
{
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->outputRezTiming("Fetching textures from cache");
+ }
+
llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl;
gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
gAgentQueryManager.mNumPendingQueries++;
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index 1edc96e165..8cba54347e 100644
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -87,6 +87,10 @@ public:
LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :
LLInventoryFetchDescendentsObserver(cof_id)
{
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->outputRezTiming("Initial wearables fetch started");
+ }
}
LLInitialWearablesFetch::~LLInitialWearablesFetch()
@@ -101,6 +105,10 @@ void LLInitialWearablesFetch::done()
// idle tick instead.
gInventory.removeObserver(this);
doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this));
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->outputRezTiming("Initial wearables fetch done");
+ }
}
void LLInitialWearablesFetch::add(InitialWearableData &data)
@@ -111,6 +119,12 @@ void LLInitialWearablesFetch::add(InitialWearableData &data)
void LLInitialWearablesFetch::processContents()
{
+ if(!gAgentAvatarp) //no need to process wearables if the agent avatar is deleted.
+ {
+ delete this;
+ return ;
+ }
+
// Fetch the wearable items from the Current Outfit Folder
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
diff --git a/indra/newview/llagentwearablesfetch.h b/indra/newview/llagentwearablesfetch.h
index 7dafab4a33..bedc445c0e 100644
--- a/indra/newview/llagentwearablesfetch.h
+++ b/indra/newview/llagentwearablesfetch.h
@@ -40,6 +40,8 @@
//--------------------------------------------------------------------
class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver
{
+ LOG_CLASS(LLInitialWearablesFetch);
+
public:
LLInitialWearablesFetch(const LLUUID& cof_id);
~LLInitialWearablesFetch();
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 663257042e..33f5373d7e 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -268,6 +268,8 @@ struct LLFoundData
class LLWearableHoldingPattern
{
+ LOG_CLASS(LLWearableHoldingPattern);
+
public:
LLWearableHoldingPattern();
~LLWearableHoldingPattern();
@@ -436,6 +438,11 @@ void LLWearableHoldingPattern::checkMissingWearables()
void LLWearableHoldingPattern::onAllComplete()
{
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->outputRezTiming("Agent wearables fetch complete");
+ }
+
if (!isMostRecent())
{
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
@@ -2363,6 +2370,8 @@ void LLAppearanceMgr::autopopulateOutfits()
// Handler for anything that's deferred until avatar de-clouds.
void LLAppearanceMgr::onFirstFullyVisible()
{
+ gAgentAvatarp->outputRezTiming("Avatar fully loaded");
+ gAgentAvatarp->reportAvatarRezTime();
gAgentAvatarp->debugAvatarVisible();
// The auto-populate is failing at the point of generating outfits
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 0861fe85a8..49fbdbf1df 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -45,6 +45,8 @@
#include "llwindow.h"
#include "llviewerstats.h"
#include "llviewerstatsrecorder.h"
+#include "llmarketplacefunctions.h"
+#include "llmarketplacenotifications.h"
#include "llmd5.h"
#include "llmeshrepository.h"
#include "llpumpio.h"
@@ -720,7 +722,9 @@ bool LLAppViewer::init()
// *NOTE:Mani - LLCurl::initClass is not thread safe.
// Called before threads are created.
- LLCurl::initClass(gSavedSettings.getBOOL("CurlUseMultipleThreads"));
+ LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"),
+ gSavedSettings.getS32("CurlMaximumNumberOfHandles"),
+ gSavedSettings.getBOOL("CurlUseMultipleThreads"));
LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ;
LLMachineID::init();
@@ -1346,17 +1350,19 @@ bool LLAppViewer::mainLoop()
{
S32 work_pending = 0;
S32 io_pending = 0;
+ F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+
{
LLFastTimer ftm(FTM_TEXTURE_CACHE);
- work_pending += LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
+ work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
}
{
LLFastTimer ftm(FTM_DECODE);
- work_pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
+ work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
}
{
LLFastTimer ftm(FTM_DECODE);
- work_pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
+ work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
}
{
@@ -4402,6 +4408,10 @@ void LLAppViewer::idle()
// update media focus
LLViewerMediaFocus::getInstance()->update();
+
+ // Update marketplace
+ LLMarketplaceInventoryImporter::update();
+ LLMarketplaceInventoryNotifications::update();
// objects and camera should be in sync, do LOD calculations now
{
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 8ca621538f..9a7cdcfa21 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -680,12 +680,29 @@ namespace action_give_inventory
std::string items;
build_items_string(inventory_selected_uuids, items);
+ int folders_count = 0;
+ std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
+
+ //traverse through selected inventory items and count folders among them
+ for ( ; it != inventory_selected_uuids.end() && folders_count <=1 ; ++it)
+ {
+ LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ if (NULL != inv_cat)
+ {
+ folders_count++;
+ }
+ }
+
+ // EXP-1599
+ // In case of sharing multiple folders, make the confirmation
+ // dialog contain a warning that only one folder can be shared at a time.
+ std::string notification = (folders_count > 1) ? "ShareFolderConfirmation" : "ShareItemsConfirmation";
LLSD substitutions;
substitutions["RESIDENTS"] = residents;
substitutions["ITEMS"] = items;
LLShareInfo::instance().mAvatarNames = avatar_names;
LLShareInfo::instance().mAvatarUuids = avatar_uuids;
- LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, LLSD(), &give_inventory_cb);
+ LLNotificationsUtil::add(notification, substitutions, LLSD(), &give_inventory_cb);
}
}
@@ -707,7 +724,7 @@ std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
if (sidepanel_inventory)
{
- inventory_selected_uuids = sidepanel_inventory->getInboxOrOutboxSelectionList();
+ inventory_selected_uuids = sidepanel_inventory->getInboxSelectionList();
}
}
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index 42e7decec1..b539ac38ed 100644..100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -75,6 +75,9 @@ void LLAvatarIconIDCache::load ()
LLUUID icon_id;
LLDate date;
+ if (line.length()<=uuid_len*2)
+ continue; // short line, bail out to prevent substr calls throwing exception.
+
std::string avatar_id_str = line.substr(0,uuid_len);
std::string icon_id_str = line.substr(uuid_len,uuid_len);
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 42de47e777..f530d10ddc 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -621,7 +621,6 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p)
panel_p.has_border = false;
panel_p.mouse_opaque = false;
panel_p.min_dim = 30;
- panel_p.max_dim = S32_MAX;
panel_p.auto_resize = true;
panel_p.user_resize = false;
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index a076374903..aabab0ccb9 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -250,6 +250,12 @@ LLIMWellChiclet::LLIMWellChiclet(const Params& p)
LLIMWellChiclet::~LLIMWellChiclet()
{
+ LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance();
+ if (im_well_window)
+ {
+ im_well_window->setSysWellChiclet(NULL);
+ }
+
LLIMMgr::getInstance()->removeSessionObserver(this);
}
@@ -296,6 +302,13 @@ void LLIMWellChiclet::createMenu()
void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
{
+ // The singleton class LLChicletBar instance might be already deleted
+ // so don't create a new one.
+ if (!LLChicletBar::instanceExists())
+ {
+ return;
+ }
+
const LLUUID& session_id = session_data["session_id"];
const S32 counter = LLChicletBar::getInstance()->getTotalUnreadIMCount();
const bool im_not_visible = !LLFloaterReg::instanceVisible("im_container")
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index a879651060..f1bc51fbe7 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -42,28 +42,6 @@ namespace
{
const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel";
- S32 get_panel_min_width(LLLayoutStack* stack, LLView* panel)
- {
- S32 minimal_width = 0;
- llassert(stack);
- if ( stack && panel && panel->getVisible() )
- {
- stack->getPanelMinSize(panel->getName(), &minimal_width);
- }
- return minimal_width;
- }
-
- S32 get_panel_max_width(LLLayoutStack* stack, LLPanel* panel)
- {
- S32 max_width = 0;
- llassert(stack);
- if ( stack && panel && panel->getVisible() )
- {
- stack->getPanelMaxSize(panel->getName(), &max_width);
- }
- return max_width;
- }
-
S32 get_curr_width(LLUICtrl* ctrl)
{
S32 cur_width = 0;
@@ -234,15 +212,8 @@ void LLChicletBar::reshape(S32 width, S32 height, BOOL called_from_parent)
{
// Firstly, update layout stack to ensure we deal with correct panel sizes.
{
- BOOL saved_anim = mToolbarStack->getAnimate();
- // Set chiclet panel to be autoresized by default.
- mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, TRUE);
- // Disable animation to prevent layout updating in several frames.
- mToolbarStack->setAnimate(FALSE);
// Force the updating of layout to reset panels collapse factor.
mToolbarStack->updateLayout();
- // Restore animate state.
- mToolbarStack->setAnimate(saved_anim);
}
// chiclet bar is narrowed
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index 65c61c4a8b..17d403bbe1 100644
--- a/indra/newview/llcommandlineparser.cpp
+++ b/indra/newview/llcommandlineparser.cpp
@@ -342,6 +342,15 @@ bool LLCommandLineParser::parseCommandLine(int argc, char **argv)
return parseAndStoreResults(clp);
}
+// TODO:
+// - Break out this funky parsing logic into separate method
+// - Unit-test it with tests like LLStringUtil::getTokens() (the command-line
+// overload that supports quoted tokens)
+// - Unless this logic offers significant semantic benefits, replace it with
+// LLStringUtil::getTokens(). This would fix a known bug: you cannot --set a
+// string-valued variable to the empty string, because empty strings are
+// eliminated below.
+
bool LLCommandLineParser::parseCommandLineString(const std::string& str)
{
// Split the string content into tokens
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index debac9dcbf..21b21c152a 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -1077,6 +1077,7 @@ BOOL LLDrawable::isVisible() const
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)
: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB)
{
+ mBridge = this;
mDrawable = root;
root->setSpatialBridge(this);
@@ -1105,6 +1106,15 @@ LLSpatialBridge::~LLSpatialBridge()
{
group->mSpatialPartition->remove(this, group);
}
+
+ //delete octree here so listeners will still be able to access bridge specific state
+ destroyTree();
+}
+
+void LLSpatialBridge::destroyTree()
+{
+ delete mOctree;
+ mOctree = NULL;
}
void LLSpatialBridge::updateSpatialExtents()
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 55b314fbb1..b002c11af5 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1285,7 +1285,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
face->setGeomIndex(0);
face->setIndicesIndex(0);
- if (buffer.isNull() || buffer->getTypeMask() != data_mask)
+ if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
{ //make a new buffer
if (sShaderLevel > 0)
{
@@ -1319,7 +1319,9 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
LLMatrix3 mat_normal(mat3);
//let getGeometryVolume know if alpha should override shiny
- if (face->getFaceColor().mV[3] < 1.f)
+ U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
+
+ if (type == LLDrawPool::POOL_ALPHA)
{
face->setPoolType(LLDrawPool::POOL_ALPHA);
}
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index b696b90d84..b58efe62ab 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -1036,51 +1036,48 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) );
LLViewerTexture* bump = NULL;
- const F32 BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD = 1000;
- if( src_image->getMaxVirtualSize() > BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD )
- {
- bump_image_map_t* entries_list = NULL;
- void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL;
+
+ bump_image_map_t* entries_list = NULL;
+ void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL;
- switch( bump_code )
- {
- case BE_BRIGHTNESS:
- entries_list = &mBrightnessEntries;
- callback_func = LLBumpImageList::onSourceBrightnessLoaded;
- break;
- case BE_DARKNESS:
- entries_list = &mDarknessEntries;
- callback_func = LLBumpImageList::onSourceDarknessLoaded;
- break;
- default:
- llassert(0);
- return NULL;
- }
+ switch( bump_code )
+ {
+ case BE_BRIGHTNESS:
+ entries_list = &mBrightnessEntries;
+ callback_func = LLBumpImageList::onSourceBrightnessLoaded;
+ break;
+ case BE_DARKNESS:
+ entries_list = &mDarknessEntries;
+ callback_func = LLBumpImageList::onSourceDarknessLoaded;
+ break;
+ default:
+ llassert(0);
+ return NULL;
+ }
- bump_image_map_t::iterator iter = entries_list->find(src_image->getID());
- if (iter != entries_list->end() && iter->second.notNull())
- {
- bump = iter->second;
- }
- else
- {
- LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
- raw->clear(0x77, 0x77, 0xFF, 0xFF);
+ bump_image_map_t::iterator iter = entries_list->find(src_image->getID());
+ if (iter != entries_list->end() && iter->second.notNull())
+ {
+ bump = iter->second;
+ }
+ else
+ {
+ LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
+ raw->clear(0x77, 0x77, 0xFF, 0xFF);
- (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
- bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image
- }
+ (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
+ bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image
+ }
- if (!src_image->hasCallbacks())
- { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again
- if (src_image->getWidth() != bump->getWidth() ||
- src_image->getHeight() != bump->getHeight())// ||
- //(LLPipeline::sRenderDeferred && bump->getComponents() != 4))
- {
- src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
- src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL );
- src_image->forceToSaveRawImage(0) ;
- }
+ if (!src_image->hasCallbacks())
+ { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again
+ if (src_image->getWidth() != bump->getWidth() ||
+ src_image->getHeight() != bump->getHeight())// ||
+ //(LLPipeline::sRenderDeferred && bump->getComponents() != 4))
+ {
+ src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
+ src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL );
+ src_image->forceToSaveRawImage(0) ;
}
}
diff --git a/indra/newview/llexternaleditor.cpp b/indra/newview/llexternaleditor.cpp
index ed1d7e860a..9480e54809 100644
--- a/indra/newview/llexternaleditor.cpp
+++ b/indra/newview/llexternaleditor.cpp
@@ -29,6 +29,9 @@
#include "lltrans.h"
#include "llui.h"
+#include "llprocess.h"
+#include "llsdutil.h"
+#include <boost/foreach.hpp>
// static
const std::string LLExternalEditor::sFilenameMarker = "%s";
@@ -45,19 +48,8 @@ LLExternalEditor::EErrorCode LLExternalEditor::setCommand(const std::string& env
return EC_NOT_SPECIFIED;
}
- // Add the filename marker if missing.
- if (cmd.find(sFilenameMarker) == std::string::npos)
- {
- cmd += " \"" + sFilenameMarker + "\"";
- llinfos << "Adding the filename marker (" << sFilenameMarker << ")" << llendl;
- }
-
string_vec_t tokens;
- if (tokenize(tokens, cmd) < 2) // 2 = bin + at least one arg (%s)
- {
- llwarns << "Error parsing editor command" << llendl;
- return EC_PARSE_ERROR;
- }
+ tokenize(tokens, cmd);
// Check executable for existence.
std::string bin_path = tokens[0];
@@ -68,51 +60,48 @@ LLExternalEditor::EErrorCode LLExternalEditor::setCommand(const std::string& env
}
// Save command.
- mProcess.setExecutable(bin_path);
- mArgs.clear();
+ mProcessParams = LLProcess::Params();
+ mProcessParams.executable = bin_path;
for (size_t i = 1; i < tokens.size(); ++i)
{
- if (i > 1) mArgs += " ";
- mArgs += "\"" + tokens[i] + "\"";
+ mProcessParams.args.add(tokens[i]);
}
- llinfos << "Setting command [" << bin_path << " " << mArgs << "]" << llendl;
+
+ // Add the filename marker if missing.
+ if (cmd.find(sFilenameMarker) == std::string::npos)
+ {
+ mProcessParams.args.add(sFilenameMarker);
+ llinfos << "Adding the filename marker (" << sFilenameMarker << ")" << llendl;
+ }
+
+ llinfos << "Setting command [" << mProcessParams << "]" << llendl;
return EC_SUCCESS;
}
LLExternalEditor::EErrorCode LLExternalEditor::run(const std::string& file_path)
{
- std::string args = mArgs;
- if (mProcess.getExecutable().empty() || args.empty())
+ if (std::string(mProcessParams.executable).empty() || mProcessParams.args.empty())
{
llwarns << "Editor command not set" << llendl;
return EC_NOT_SPECIFIED;
}
- // Substitute the filename marker in the command with the actual passed file name.
- LLStringUtil::replaceString(args, sFilenameMarker, file_path);
-
- // Split command into separate tokens.
- string_vec_t tokens;
- tokenize(tokens, args);
+ // Copy params block so we can replace sFilenameMarker
+ LLProcess::Params params;
+ params.executable = mProcessParams.executable;
- // Set process arguments taken from the command.
- mProcess.clearArguments();
- for (string_vec_t::const_iterator arg_it = tokens.begin(); arg_it != tokens.end(); ++arg_it)
- {
- mProcess.addArgument(*arg_it);
- }
-
- // Run the editor.
- llinfos << "Running editor command [" << mProcess.getExecutable() + " " + args << "]" << llendl;
- int result = mProcess.launch();
- if (result == 0)
+ // Substitute the filename marker in the command with the actual passed file name.
+ BOOST_FOREACH(const std::string& arg, mProcessParams.args)
{
- // Prevent killing the process in destructor (will add it to the zombies list).
- mProcess.orphan();
+ std::string fixed(arg);
+ LLStringUtil::replaceString(fixed, sFilenameMarker, file_path);
+ params.args.add(fixed);
}
- return result == 0 ? EC_SUCCESS : EC_FAILED_TO_RUN;
+ // Run the editor. Prevent killing the process in destructor.
+ params.autokill = false;
+ return LLProcess::create(params) ? EC_SUCCESS : EC_FAILED_TO_RUN;
}
// static
@@ -130,6 +119,12 @@ std::string LLExternalEditor::getErrorMessage(EErrorCode code)
return LLTrans::getString("Unknown");
}
+// TODO:
+// - Unit-test this with tests like LLStringUtil::getTokens() (the
+// command-line overload that supports quoted tokens)
+// - Unless there are significant semantic differences, eliminate this method
+// and use LLStringUtil::getTokens() instead.
+
// static
size_t LLExternalEditor::tokenize(string_vec_t& tokens, const std::string& str)
{
diff --git a/indra/newview/llexternaleditor.h b/indra/newview/llexternaleditor.h
index ef5db56c6e..fd2c25020c 100644
--- a/indra/newview/llexternaleditor.h
+++ b/indra/newview/llexternaleditor.h
@@ -27,7 +27,7 @@
#ifndef LL_LLEXTERNALEDITOR_H
#define LL_LLEXTERNALEDITOR_H
-#include <llprocesslauncher.h>
+#include "llprocess.h"
/**
* Usage:
@@ -97,9 +97,7 @@ private:
*/
static const std::string sSetting;
-
- std::string mArgs;
- LLProcessLauncher mProcess;
+ LLProcess::Params mProcessParams;
};
#endif // LL_LLEXTERNALEDITOR_H
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 6dbeae6677..cd33a19a2a 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -693,6 +693,49 @@ static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 of
tex_coord.mV[1] = t;
}
+// Transform the texture coordinates for this face.
+static void xform4a(LLVector4a &tex_coord, const LLVector4a& trans, const LLVector4Logical& mask, const LLVector4a& rot0, const LLVector4a& rot1, const LLVector4a& offset, const LLVector4a& scale)
+{
+ //tex coord is two coords, <s0, t0, s1, t1>
+ LLVector4a st;
+
+ // Texture transforms are done about the center of the face.
+ st.setAdd(tex_coord, trans);
+
+ // Handle rotation
+ LLVector4a rot_st;
+
+ // <s0 * cosAng, s0*-sinAng, s1*cosAng, s1*-sinAng>
+ LLVector4a s0;
+ s0.splat(st, 0);
+ LLVector4a s1;
+ s1.splat(st, 2);
+ LLVector4a ss;
+ ss.setSelectWithMask(mask, s1, s0);
+
+ LLVector4a a;
+ a.setMul(rot0, ss);
+
+ // <t0*sinAng, t0*cosAng, t1*sinAng, t1*cosAng>
+ LLVector4a t0;
+ t0.splat(st, 1);
+ LLVector4a t1;
+ t1.splat(st, 3);
+ LLVector4a tt;
+ tt.setSelectWithMask(mask, t1, t0);
+
+ LLVector4a b;
+ b.setMul(rot1, tt);
+
+ st.setAdd(a,b);
+
+ // Then scale
+ st.mul(scale);
+
+ // Then offset
+ tex_coord.setAdd(st, offset);
+}
+
bool less_than_max_mag(const LLVector4a& vec)
{
@@ -1060,6 +1103,16 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail");
+static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos");
+static LLFastTimer::DeclareTimer FTM_FACE_TEXTURE_INDEX_STORE("TexIdx");
+static LLFastTimer::DeclareTimer FTM_FACE_POSITION_PAD("Pad");
+static LLFastTimer::DeclareTimer FTM_FACE_TEX_DEFAULT("Default");
+static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK("Quick");
+static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_NO_XFORM("No Xform");
+static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_XFORM("Xform");
+
+static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_PLANAR("Quick Planar");
BOOL LLFace::getGeometryVolume(const LLVolume& volume,
const S32 &f,
@@ -1078,7 +1131,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
updateRebuildFlags();
}
- bool map_range = gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;
+
+ //don't use map range (generates many redundant unmap calls)
+ bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;
if (mVertexBuffer.notNull())
{
@@ -1104,16 +1159,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
LLStrider<LLVector3> vert;
- LLVector4a* vertices = NULL;
LLStrider<LLVector2> tex_coords;
LLStrider<LLVector2> tex_coords2;
- LLVector4a* normals = NULL;
LLStrider<LLVector3> norm;
LLStrider<LLColor4U> colors;
- LLVector4a* binormals = NULL;
LLStrider<LLVector3> binorm;
LLStrider<U16> indicesp;
- LLVector4a* weights = NULL;
LLStrider<LLVector4> wght;
BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME);
@@ -1202,7 +1253,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLFastTimer t(FTM_FACE_GEOM_INDEX);
mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range);
- __m128i* dst = (__m128i*) indicesp.get();
+ volatile __m128i* dst = (__m128i*) indicesp.get();
__m128i* src = (__m128i*) vf.mIndices;
__m128i offset = _mm_set1_epi16(index_offset);
@@ -1211,12 +1262,17 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
for (S32 i = 0; i < end; i++)
{
__m128i res = _mm_add_epi16(src[i], offset);
- _mm_storeu_si128(dst+i, res);
+ _mm_storeu_si128((__m128i*) dst++, res);
}
- for (S32 i = end*8; i < num_indices; ++i)
{
- indicesp[i] = vf.mIndices[i]+index_offset;
+ LLFastTimer t(FTM_FACE_GEOM_INDEX_TAIL);
+ U16* idx = (U16*) dst;
+
+ for (S32 i = end*8; i < num_indices; ++i)
+ {
+ *idx++ = vf.mIndices[i]+index_offset;
+ }
}
if (map_range)
@@ -1373,19 +1429,48 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
{
+ LLFastTimer t(FTM_FACE_TEX_QUICK);
if (!do_tex_mat)
{
if (!do_xform)
{
+ LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);
LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
}
else
{
- for (S32 i = 0; i < num_vertices; i++)
+ LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM);
+ F32* dst = (F32*) tex_coords.get();
+ LLVector4a* src = (LLVector4a*) vf.mTexCoords;
+
+ LLVector4a trans;
+ trans.splat(-0.5f);
+
+ LLVector4a rot0;
+ rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang);
+
+ LLVector4a rot1;
+ rot1.set(sin_ang, cos_ang, sin_ang, cos_ang);
+
+ LLVector4a scale;
+ scale.set(ms, mt, ms, mt);
+
+ LLVector4a offset;
+ offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f);
+
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<2>();
+ mask.setElement<3>();
+
+ U32 count = num_vertices/2 + num_vertices%2;
+
+ for (S32 i = 0; i < count; i++)
{
- LLVector2 tc(vf.mTexCoords[i]);
- xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
- *tex_coords++ = tc;
+ LLVector4a res = *src++;
+ xform4a(res, trans, mask, rot0, rot1, offset, scale);
+ res.store4a(dst);
+ dst += 4;
}
}
}
@@ -1407,6 +1492,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
else
{ //no bump, no atlas, tex gen planar
+ LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);
if (do_tex_mat)
{
for (S32 i = 0; i < num_vertices; i++)
@@ -1451,6 +1537,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
else
{ //either bump mapped or in atlas, just do the whole expensive loop
+ LLFastTimer t(FTM_FACE_TEX_DEFAULT);
mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);
std::vector<LLVector2> bump_tc;
@@ -1642,44 +1729,55 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
llassert(num_vertices > 0);
mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
- vertices = (LLVector4a*) vert.get();
-
+
+
LLMatrix4a mat_vert;
mat_vert.loadu(mat_vert_in);
LLVector4a* src = vf.mPositions;
- LLVector4a* dst = vertices;
+ volatile F32* dst = (volatile F32*) vert.get();
- LLVector4a* end = dst+num_vertices;
- do
- {
- mat_vert.affineTransform(*src++, *dst++);
- }
- while(dst < end);
+ volatile F32* end = dst+num_vertices*4;
+ LLVector4a res;
- F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0);
+ LLVector4a texIdx;
+ F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0);
llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
- F32 *index_dst = (F32*) vertices;
- F32 *index_end = (F32*) end;
- index_dst += 3;
- index_end += 3;
- do
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
+
+ texIdx.set(0,0,0,index);
+
{
- *index_dst = index;
- index_dst += 4;
+ LLFastTimer t(FTM_FACE_POSITION_STORE);
+ LLVector4a tmp;
+
+ do
+ {
+ mat_vert.affineTransform(*src++, res);
+ tmp.setSelectWithMask(mask, texIdx, res);
+ tmp.store4a((F32*) dst);
+ dst += 4;
+ }
+ while(dst < end);
}
- while (index_dst < index_end);
-
- S32 aligned_pad_vertices = mGeomCount - num_vertices;
- LLVector4a* last_vec = end - 1;
- while (aligned_pad_vertices > 0)
+
{
- --aligned_pad_vertices;
- *dst++ = *last_vec;
+ LLFastTimer t(FTM_FACE_POSITION_PAD);
+ S32 aligned_pad_vertices = mGeomCount - num_vertices;
+ res.set(res[0], res[1], res[2], 0.f);
+
+ while (aligned_pad_vertices > 0)
+ {
+ --aligned_pad_vertices;
+ res.store4a((F32*) dst);
+ dst += 4;
+ }
}
-
+
if (map_range)
{
mVertexBuffer->flush();
@@ -1690,14 +1788,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
LLFastTimer t(FTM_FACE_GEOM_NORMAL);
mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
- normals = (LLVector4a*) norm.get();
+ F32* normals = (F32*) norm.get();
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a normal;
mat_normal.rotate(vf.mNormals[i], normal);
normal.normalize3fast();
- normals[i] = normal;
+ normal.store4a(normals);
+ normals += 4;
}
if (map_range)
@@ -1710,14 +1809,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);
- binormals = (LLVector4a*) binorm.get();
+ F32* binormals = (F32*) binorm.get();
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a binormal;
mat_normal.rotate(vf.mBinormals[i], binormal);
binormal.normalize3fast();
- binormals[i] = binormal;
+ binormal.store4a(binormals);
+ binormals += 4;
}
if (map_range)
@@ -1730,8 +1830,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
LLFastTimer t(FTM_FACE_GEOM_WEIGHTS);
mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);
- weights = (LLVector4a*) wght.get();
- LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
+ F32* weights = (F32*) wght.get();
+ LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
if (map_range)
{
mVertexBuffer->flush();
@@ -1750,7 +1850,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
src.loadua((F32*) vec);
- LLVector4a* dst = (LLVector4a*) colors.get();
+ F32* dst = (F32*) colors.get();
S32 num_vecs = num_vertices/4;
if (num_vertices%4 > 0)
{
@@ -1759,7 +1859,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
for (S32 i = 0; i < num_vecs; i++)
{
- dst[i] = src;
+ src.store4a(dst);
+ dst += 4;
}
if (map_range)
@@ -1789,7 +1890,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
src.loadua((F32*) vec);
- LLVector4a* dst = (LLVector4a*) emissive.get();
+ F32* dst = (F32*) emissive.get();
S32 num_vecs = num_vertices/4;
if (num_vertices%4 > 0)
{
@@ -1798,7 +1899,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
for (S32 i = 0; i < num_vecs; i++)
{
- dst[i] = src;
+ src.store4a(dst);
+ dst += 4;
}
if (map_range)
@@ -1821,6 +1923,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mTexExtents[1][1] *= et ;
}
+
mLastVertexBuffer = mVertexBuffer;
mLastGeomCount = mGeomCount;
mLastGeomIndex = mGeomIndex;
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 4f2fd47488..f4b6dc2c81 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -405,8 +405,8 @@ LLFavoritesBarCtrl::~LLFavoritesBarCtrl()
{
gInventory.removeObserver(this);
- delete mOverflowMenuHandle.get();
- delete mContextMenuHandle.get();
+ if (mOverflowMenuHandle.get()) mOverflowMenuHandle.get()->die();
+ if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
}
BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 4897cf1885..8024755e86 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -58,6 +58,7 @@ LLFilePicker LLFilePicker::sInstance;
#define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0"
#define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
+#define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0"
#endif
//
@@ -213,6 +214,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
mOFN.lpstrFilter = MODEL_FILTER \
L"\0";
break;
+ case FFLOAD_SCRIPT:
+ mOFN.lpstrFilter = SCRIPT_FILTER \
+ L"\0";
+ break;
default:
res = FALSE;
break;
@@ -497,6 +502,14 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
L"Compressed Images (*.j2c)\0*.j2c\0" \
L"\0";
break;
+ case FFSAVE_SCRIPT:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE);
+ }
+ mOFN.lpstrDefExt = L"txt";
+ mOFN.lpstrFilter = L"LSL Files (*.lsl)\0*.lsl\0" L"\0";
+ break;
default:
return FALSE;
}
@@ -620,6 +633,14 @@ Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callB
result = false;
}
}
+ else if (filter == FFLOAD_SCRIPT)
+ {
+ if (fileInfo.filetype != 'LSL ' &&
+ (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("lsl"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) )
+ {
+ result = false;
+ }
+ }
if (fileInfo.extension)
{
@@ -766,6 +787,12 @@ OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& fi
extension = CFSTR(".j2c");
break;
+ case FFSAVE_SCRIPT:
+ type = 'LSL ';
+ creator = '\?\?\?\?';
+ extension = CFSTR(".lsl");
+ break;
+
case FFSAVE_ALL:
default:
type = '\?\?\?\?';
@@ -1192,7 +1219,12 @@ static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker)
add_common_filters_to_gtkchooser(gfilter, picker, filtername);
return filtername;
}
-
+
+static std::string add_script_filter_to_gtkchooser(GtkWindow *picker)
+{
+ return add_simple_mime_filter_to_gtkchooser(picker, "text/plain",
+ LLTrans::getString("script_files") + " (*.lsl)");
+}
BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
{
@@ -1258,6 +1290,10 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
LLTrans::getString("compressed_image_files") + " (*.j2c)");
suggest_ext = ".j2c";
break;
+ case FFSAVE_SCRIPT:
+ caption += add_script_filter_to_gtkchooser(picker);
+ suggest_ext = ".lsl";
+ break;
default:;
break;
}
@@ -1323,6 +1359,9 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
case FFLOAD_IMAGE:
filtername = add_imageload_filter_to_gtkchooser(picker);
break;
+ case FFLOAD_SCRIPT:
+ filtername = add_script_filter_to_gtkchooser(picker);
+ break;
default:;
break;
}
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index cd843a8f33..a4d5d68ff5 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -84,6 +84,7 @@ public:
FFLOAD_RAW = 8,
FFLOAD_MODEL = 9,
FFLOAD_COLLADA = 10,
+ FFLOAD_SCRIPT = 11,
};
enum ESaveFilter
@@ -103,6 +104,7 @@ public:
FFSAVE_J2C = 12,
FFSAVE_PNG = 13,
FFSAVE_JPEG = 14,
+ FFSAVE_SCRIPT = 15,
};
// open the dialog. This is a modal operation
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 659e52271a..05d73c2416 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -271,7 +271,7 @@ void LLFloaterColorPicker::destroyUI ()
if ( mSwatchView )
{
this->removeChild ( mSwatchView );
- delete mSwatchView;
+ mSwatchView->die();;
mSwatchView = NULL;
}
}
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 69de15d9ea..92ee8ddac6 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -63,6 +63,7 @@
const S32 PREVIEW_BORDER_WIDTH = 2;
const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
+const S32 PREVIEW_VPAD = -24; // yuk, hard coded
const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16;
const S32 PREVIEW_TEXTURE_HEIGHT = 320;
@@ -99,7 +100,7 @@ BOOL LLFloaterImagePreview::postBuild()
childSetCommitCallback("clothing_type_combo", onPreviewTypeCommit, this);
mPreviewRect.set(PREVIEW_HPAD,
- PREVIEW_TEXTURE_HEIGHT,
+ PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD,
getRect().getWidth() - PREVIEW_HPAD,
PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);
@@ -271,13 +272,13 @@ void LLFloaterImagePreview::draw()
gGL.begin( LLRender::QUADS );
{
gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop);
- gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
+ gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom);
gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom);
gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop);
- gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
+ gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
}
gGL.end();
@@ -303,13 +304,13 @@ void LLFloaterImagePreview::draw()
gGL.begin( LLRender::QUADS );
{
gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
+ gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
gGL.texCoord2f(0.f, 0.f);
gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
gGL.texCoord2f(1.f, 0.f);
gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
+ gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
}
gGL.end();
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index b13a9aab88..95da8ff948 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2025,7 +2025,6 @@ void LLPanelLandOptions::refresh()
}
mSeeAvatarsCtrl->set(parcel->getSeeAVs());
- mSeeAvatarsCtrl->setLabel(getString("see_avs_text"));
mSeeAvatarsCtrl->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData());
BOOL can_change_landing_point = LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
@@ -2475,27 +2474,6 @@ void LLPanelLandAccess::refresh()
mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix);
}
}
-
- LLCheckBoxWithTBAcess* maturity_checkbox = (LLCheckBoxWithTBAcess*) getChild<LLCheckBoxCtrl>( "public_access");
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
- if(region)
- {
- LLTextBox* maturity_textbox = maturity_checkbox->getTextBox();
- insert_maturity_into_textbox(maturity_textbox, gFloaterView->getParentFloater(this), getString("allow_public_access"));
- maturity_checkbox->reshape(maturity_checkbox->getRect().getWidth(), maturity_checkbox->getRect().getHeight(), FALSE);
- }
- else
- {
- std::string maturity_string = getString("allow_public_access");
- size_t maturity_pos = maturity_string.find(MATURITY);
-
- if (maturity_pos != std::string::npos)
- {
- maturity_string.replace(maturity_pos, MATURITY.length(), std::string(""));
- }
-
- maturity_checkbox->setLabel(maturity_string);
- }
if(parcel->getRegionDenyAnonymousOverride())
{
diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
index b5f1b967df..895e16adef 100644
--- a/indra/newview/llfloatermediasettings.cpp
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -212,10 +212,13 @@ void LLFloaterMediaSettings::commitFields()
//static
void LLFloaterMediaSettings::clearValues( bool editable)
{
- // clean up all panels before updating
- sInstance->mPanelMediaSettingsGeneral ->clearValues(sInstance->mPanelMediaSettingsGeneral, editable);
- sInstance->mPanelMediaSettingsSecurity ->clearValues(sInstance->mPanelMediaSettingsSecurity, editable);
- sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions, editable);
+ if (sInstance)
+ {
+ // clean up all panels before updating
+ sInstance->mPanelMediaSettingsGeneral ->clearValues(sInstance->mPanelMediaSettingsGeneral, editable);
+ sInstance->mPanelMediaSettingsSecurity ->clearValues(sInstance->mPanelMediaSettingsSecurity, editable);
+ sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions, editable);
+ }
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 64bdcccd9f..9122e5a8f5 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -3969,7 +3969,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices();
if (num_indices > 2)
{
- glodInsertElements(mObject[mdl], i, GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, mVertexBuffer[5][mdl][i]->getIndicesPointer(), 0, 0.f);
+ glodInsertElements(mObject[mdl], i, GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, (U8*) mVertexBuffer[5][mdl][i]->getIndicesPointer(), 0, 0.f);
}
tri_count += num_indices/3;
stop_gloderror();
@@ -4083,14 +4083,14 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
{
buff->allocateBuffer(sizes[i*2+1], sizes[i*2], true);
buff->setBuffer(type_mask);
- glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, buff->getIndicesPointer());
+ glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, (U8*) buff->getIndicesPointer());
stop_gloderror();
}
else
{ //this face was eliminated, create a dummy triangle (one vertex, 3 indices, all 0)
buff->allocateBuffer(1, 3, true);
- memset(buff->getMappedData(), 0, buff->getSize());
- memset(buff->getIndicesPointer(), 0, buff->getIndicesSize());
+ memset((U8*) buff->getMappedData(), 0, buff->getSize());
+ memset((U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize());
}
buff->validateRange(0, buff->getNumVerts()-1, buff->getNumIndices(), 0);
@@ -4880,8 +4880,8 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget )
LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0);
buff->allocateBuffer(1, 3, true);
- memset( buff->getMappedData(), 0, buff->getSize() );
- memset( buff->getIndicesPointer(), 0, buff->getIndicesSize() );
+ memset( (U8*) buff->getMappedData(), 0, buff->getSize() );
+ memset( (U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize() );
buff->validateRange( 0, buff->getNumVerts()-1, buff->getNumIndices(), 0 );
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index ae95d4392a..66f0fc3cd7 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -204,3 +204,24 @@ BOOL LLFloaterSoundPreview::postBuild()
getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
return TRUE;
}
+
+
+//-----------------------------------------------------------------------------
+// LLFloaterScriptPreview()
+//-----------------------------------------------------------------------------
+
+LLFloaterScriptPreview::LLFloaterScriptPreview(const LLSD& filename )
+ : LLFloaterNameDesc(filename)
+{
+ mIsText = TRUE;
+}
+
+BOOL LLFloaterScriptPreview::postBuild()
+{
+ if (!LLFloaterNameDesc::postBuild())
+ {
+ return FALSE;
+ }
+ getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
+ return TRUE;
+}
diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h
index 7381a6334a..69bbccaf80 100644
--- a/indra/newview/llfloaternamedesc.h
+++ b/indra/newview/llfloaternamedesc.h
@@ -51,6 +51,7 @@ protected:
protected:
BOOL mIsAudio;
+ bool mIsText;
std::string mFilenameAndPath;
std::string mFilename;
@@ -62,5 +63,12 @@ public:
LLFloaterSoundPreview(const LLSD& filename );
virtual BOOL postBuild();
};
-
+
+class LLFloaterScriptPreview : public LLFloaterNameDesc
+{
+public:
+ LLFloaterScriptPreview(const LLSD& filename );
+ virtual BOOL postBuild();
+};
+
#endif // LL_LLFLOATERNAMEDESC_H
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
index 29af81d64c..2681d4b34d 100644
--- a/indra/newview/llfloaternotificationsconsole.cpp
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -220,7 +220,7 @@ void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open
void LLFloaterNotificationConsole::removeChannel(const std::string& name)
{
LLPanel* panelp = getChild<LLPanel>(name);
- getChildRef<LLLayoutStack>("notification_channels").removePanel(panelp);
+ getChildRef<LLView>("notification_channels").removeChild(panelp);
delete panelp;
updateResizeLimits();
diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index 8b6619def2..4bfef8b45f 100644
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -162,26 +162,66 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
{
parent_category_id = gInventory.getRootFolderID();
}
+
+ LLCategoryCreate* cat_data = new LLCategoryCreate(object_id, wear);
+
LLUUID category_id = gInventory.createNewCategory(parent_category_id,
- LLFolderType::FT_NONE,
- name);
+ LLFolderType::FT_NONE,
+ name,
+ callbackCreateInventoryCategory,
+ (void*)cat_data);
+
+ //If we get a null category ID, we are using a capability in createNewCategory and we will
+ //handle the following in the callbackCreateInventoryCategory routine.
+ if ( category_id.notNull() )
+ {
+ delete cat_data;
+
+ LLCatAndWear* data = new LLCatAndWear;
+ data->mCatID = category_id;
+ data->mWear = wear;
+ data->mFolderResponded = false;
+
+ // Copy and/or move the items into the newly created folder.
+ // Ignore any "you're going to break this item" messages.
+ BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE,
+ callbackMoveInventory,
+ (void*)data);
+ if (!success)
+ {
+ delete data;
+ data = NULL;
- LLCatAndWear* data = new LLCatAndWear;
- data->mCatID = category_id;
- data->mWear = wear;
+ LLNotificationsUtil::add("OpenObjectCannotCopy");
+ }
+ }
+}
+// static
+void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, void* data)
+{
+ LLCategoryCreate* cat_data = (LLCategoryCreate*)data;
+
+ LLUUID category_id = result["folder_id"].asUUID();
+ LLCatAndWear* wear_data = new LLCatAndWear;
+
+ wear_data->mCatID = category_id;
+ wear_data->mWear = cat_data->mWear;
+ wear_data->mFolderResponded = true;
+
// Copy and/or move the items into the newly created folder.
// Ignore any "you're going to break this item" messages.
- BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE,
+ BOOL success = move_inv_category_world_to_agent(cat_data->mObjectID, category_id, TRUE,
callbackMoveInventory,
- (void*)data);
+ (void*)wear_data);
if (!success)
{
- delete data;
- data = NULL;
-
+ delete wear_data;
+ wear_data = NULL;
+
LLNotificationsUtil::add("OpenObjectCannotCopy");
}
+ delete cat_data;
}
// static
diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h
index 0706e99f16..bf7fe69c65 100644
--- a/indra/newview/llfloateropenobject.h
+++ b/indra/newview/llfloateropenobject.h
@@ -45,10 +45,20 @@ public:
void dirty();
+ class LLCategoryCreate
+ {
+ public:
+ LLCategoryCreate(LLUUID object_id, bool wear) : mObjectID(object_id), mWear(wear) {}
+ public:
+ LLUUID mObjectID;
+ bool mWear;
+ };
+
struct LLCatAndWear
{
LLUUID mCatID;
bool mWear;
+ bool mFolderResponded;
};
protected:
@@ -62,6 +72,7 @@ protected:
void onClickMoveToInventory();
void onClickMoveAndWear();
+ static void callbackCreateInventoryCategory(const LLSD& result, void* data);
static void callbackMoveInventory(S32 result, void* data);
private:
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
new file mode 100644
index 0000000000..540f977305
--- /dev/null
+++ b/indra/newview/llfloateroutbox.cpp
@@ -0,0 +1,567 @@
+/**
+ * @file llfloateroutbox.cpp
+ * @brief Implementation of the merchant outbox window
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloateroutbox.h"
+
+#include "llfloaterreg.h"
+#include "llfolderview.h"
+#include "llinventorybridge.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventoryobserver.h"
+#include "llinventorypanel.h"
+#include "llmarketplacefunctions.h"
+#include "llnotificationhandler.h"
+#include "llnotificationmanager.h"
+#include "llnotificationsutil.h"
+#include "lltextbox.h"
+#include "lltransientfloatermgr.h"
+#include "lltrans.h"
+#include "llviewernetwork.h"
+#include "llwindowshade.h"
+
+#define USE_WINDOWSHADE_DIALOGS 0
+
+
+///----------------------------------------------------------------------------
+/// LLOutboxNotification class
+///----------------------------------------------------------------------------
+
+bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& notify)
+{
+ LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox");
+
+ outbox_floater->showNotification(notify);
+
+ return false;
+}
+
+
+///----------------------------------------------------------------------------
+/// LLOutboxAddedObserver helper class
+///----------------------------------------------------------------------------
+
+class LLOutboxAddedObserver : public LLInventoryCategoryAddedObserver
+{
+public:
+ LLOutboxAddedObserver(LLFloaterOutbox * outboxFloater)
+ : LLInventoryCategoryAddedObserver()
+ , mOutboxFloater(outboxFloater)
+ {
+ }
+
+ void done()
+ {
+ for (cat_vec_t::iterator it = mAddedCategories.begin(); it != mAddedCategories.end(); ++it)
+ {
+ LLViewerInventoryCategory* added_category = *it;
+
+ LLFolderType::EType added_category_type = added_category->getPreferredType();
+
+ if (added_category_type == LLFolderType::FT_OUTBOX)
+ {
+ mOutboxFloater->setupOutbox(added_category->getUUID());
+ }
+ }
+ }
+
+private:
+ LLFloaterOutbox * mOutboxFloater;
+};
+
+///----------------------------------------------------------------------------
+/// LLFloaterOutbox
+///----------------------------------------------------------------------------
+
+LLFloaterOutbox::LLFloaterOutbox(const LLSD& key)
+ : LLFloater(key)
+ , mCategoriesObserver(NULL)
+ , mCategoryAddedObserver(NULL)
+ , mImportBusy(false)
+ , mImportButton(NULL)
+ , mInventoryFolderCountText(NULL)
+ , mInventoryImportInProgress(NULL)
+ , mInventoryPlaceholder(NULL)
+ , mInventoryText(NULL)
+ , mInventoryTitle(NULL)
+ , mOutboxId(LLUUID::null)
+ , mOutboxInventoryPanel(NULL)
+ , mOutboxItemCount(0)
+ , mOutboxTopLevelDropZone(NULL)
+ , mWindowShade(NULL)
+{
+}
+
+LLFloaterOutbox::~LLFloaterOutbox()
+{
+ if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
+ {
+ gInventory.removeObserver(mCategoriesObserver);
+ }
+ delete mCategoriesObserver;
+
+ if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
+ {
+ gInventory.removeObserver(mCategoryAddedObserver);
+ }
+ delete mCategoryAddedObserver;
+}
+
+BOOL LLFloaterOutbox::postBuild()
+{
+ mInventoryFolderCountText = getChild<LLTextBox>("outbox_folder_count");
+ mInventoryImportInProgress = getChild<LLView>("import_progress_indicator");
+ mInventoryPlaceholder = getChild<LLView>("outbox_inventory_placeholder_panel");
+ mInventoryText = mInventoryPlaceholder->getChild<LLTextBox>("outbox_inventory_placeholder_text");
+ mInventoryTitle = mInventoryPlaceholder->getChild<LLTextBox>("outbox_inventory_placeholder_title");
+
+ mImportButton = getChild<LLButton>("outbox_import_btn");
+ mImportButton->setCommitCallback(boost::bind(&LLFloaterOutbox::onImportButtonClicked, this));
+
+ mOutboxTopLevelDropZone = getChild<LLPanel>("outbox_generic_drag_target");
+
+ LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLFloaterOutbox::onFocusReceived, this));
+
+ return TRUE;
+}
+
+void LLFloaterOutbox::onClose(bool app_quitting)
+{
+ if (mWindowShade)
+ {
+ delete mWindowShade;
+
+ mWindowShade = NULL;
+ }
+}
+
+void LLFloaterOutbox::onOpen(const LLSD& key)
+{
+ //
+ // Look for an outbox and set up the inventory API
+ //
+
+ if (mOutboxId.isNull())
+ {
+ const bool do_not_create_folder = false;
+ const bool do_not_find_in_library = false;
+
+ const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library);
+
+ if (outbox_id.isNull())
+ {
+ // Observe category creation to catch outbox creation
+ mCategoryAddedObserver = new LLOutboxAddedObserver(this);
+ gInventory.addObserver(mCategoryAddedObserver);
+ }
+ else
+ {
+ setupOutbox(outbox_id);
+ }
+ }
+
+ updateView();
+
+ //
+ // Trigger fetch of outbox contents
+ //
+
+ fetchOutboxContents();
+}
+
+void LLFloaterOutbox::onFocusReceived()
+{
+ fetchOutboxContents();
+}
+
+void LLFloaterOutbox::fetchOutboxContents()
+{
+ if (mOutboxId.notNull())
+ {
+ LLInventoryModelBackgroundFetch::instance().start(mOutboxId);
+ }
+}
+
+void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
+{
+ llassert(outboxId.notNull());
+ llassert(mOutboxId.isNull());
+ llassert(mCategoriesObserver == NULL);
+
+ mOutboxId = outboxId;
+
+ // No longer need to observe new category creation
+ if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
+ {
+ gInventory.removeObserver(mCategoryAddedObserver);
+ delete mCategoryAddedObserver;
+ mCategoryAddedObserver = NULL;
+ }
+
+ // Create observer for outbox modifications
+ mCategoriesObserver = new LLInventoryCategoriesObserver();
+ gInventory.addObserver(mCategoriesObserver);
+
+ mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
+
+ //
+ // Set up the outbox inventory view
+ //
+
+ mOutboxInventoryPanel =
+ LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml",
+ mInventoryPlaceholder->getParent(),
+ LLInventoryPanel::child_registry_t::instance());
+
+ llassert(mOutboxInventoryPanel);
+
+ // Reshape the inventory to the proper size
+ LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect();
+ mOutboxInventoryPanel->setShape(inventory_placeholder_rect);
+
+ // Set the sort order newest to oldest
+ mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ mOutboxInventoryPanel->getFilter()->markDefault();
+
+ fetchOutboxContents();
+
+ //
+ // Initialize the marketplace import API
+ //
+
+ LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance();
+
+ importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
+ importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
+ importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
+ importer.initialize();
+}
+
+void LLFloaterOutbox::setStatusString(const std::string& statusString)
+{
+ llassert(mInventoryFolderCountText != NULL);
+
+ mInventoryFolderCountText->setText(statusString);
+}
+
+void LLFloaterOutbox::updateFolderCount()
+{
+ S32 item_count = 0;
+
+ if (mOutboxId.notNull())
+ {
+ LLInventoryModel::cat_array_t * cats;
+ LLInventoryModel::item_array_t * items;
+ gInventory.getDirectDescendentsOf(mOutboxId, cats, items);
+
+ item_count = cats->count() + items->count();
+ }
+
+ mOutboxItemCount = item_count;
+
+ if (!mImportBusy)
+ {
+ updateFolderCountStatus();
+ }
+}
+
+void LLFloaterOutbox::updateFolderCountStatus()
+{
+ if (mOutboxInventoryPanel)
+ {
+ switch (mOutboxItemCount)
+ {
+ case 0: setStatusString(getString("OutboxFolderCount0")); break;
+ case 1: setStatusString(getString("OutboxFolderCount1")); break;
+ default:
+ {
+ std::string item_count_str = llformat("%d", mOutboxItemCount);
+
+ LLStringUtil::format_map_t args;
+ args["[NUM]"] = item_count_str;
+
+ setStatusString(getString("OutboxFolderCountN", args));
+ break;
+ }
+ }
+ }
+
+ mImportButton->setEnabled(mOutboxItemCount > 0);
+}
+
+void LLFloaterOutbox::updateView()
+{
+ updateFolderCount();
+
+ if (mOutboxItemCount > 0)
+ {
+ mOutboxInventoryPanel->setVisible(TRUE);
+ mInventoryPlaceholder->setVisible(FALSE);
+ }
+ else
+ {
+ if (mOutboxInventoryPanel)
+ {
+ mOutboxInventoryPanel->setVisible(FALSE);
+ }
+
+ mInventoryPlaceholder->setVisible(TRUE);
+
+ std::string outbox_text;
+ std::string outbox_title;
+ std::string outbox_tooltip;
+
+ const LLSD& subs = getMarketplaceStringSubstitutions();
+
+ if (mOutboxId.notNull())
+ {
+ outbox_text = LLTrans::getString("InventoryOutboxNoItems", subs);
+ outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle");
+ outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip");
+ }
+ else
+ {
+ outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", subs);
+ outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle");
+ outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip");
+ }
+
+ mInventoryText->setValue(outbox_text);
+ mInventoryTitle->setValue(outbox_title);
+ mInventoryPlaceholder->getParent()->setToolTip(outbox_tooltip);
+ }
+}
+
+bool isAccepted(EAcceptance accept)
+{
+ return (accept >= ACCEPT_YES_COPY_SINGLE);
+}
+
+BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ if ((mOutboxInventoryPanel == NULL) ||
+ (mWindowShade && mWindowShade->isShown()) ||
+ LLMarketplaceInventoryImporter::getInstance()->isImportInProgress())
+ {
+ return FALSE;
+ }
+
+ LLView * handled_view = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ BOOL handled = (handled_view != NULL);
+
+ // Determine if the mouse is inside the inventory panel itself or just within the floater
+ bool pointInInventoryPanel = false;
+ bool pointInInventoryPanelChild = false;
+ LLFolderView * root_folder = mOutboxInventoryPanel->getRootFolder();
+ if (mOutboxInventoryPanel->getVisible())
+ {
+ S32 inv_x, inv_y;
+ localPointToOtherView(x, y, &inv_x, &inv_y, mOutboxInventoryPanel);
+
+ pointInInventoryPanel = mOutboxInventoryPanel->getRect().pointInRect(inv_x, inv_y);
+
+ LLView * inventory_panel_child_at_point = mOutboxInventoryPanel->childFromPoint(inv_x, inv_y, true);
+ pointInInventoryPanelChild = (inventory_panel_child_at_point != root_folder);
+ }
+
+ // Pass all drag and drop for this floater to the outbox inventory control
+ if (!handled || !isAccepted(*accept))
+ {
+ // Handle the drag and drop directly to the root of the outbox if we're not in the inventory panel
+ // (otherwise the inventory panel itself will handle the drag and drop operation, without any override)
+ if (!pointInInventoryPanel)
+ {
+ handled = root_folder->handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ }
+
+ mOutboxTopLevelDropZone->setBackgroundVisible(handled && !drop && isAccepted(*accept));
+ }
+ else
+ {
+ mOutboxTopLevelDropZone->setBackgroundVisible(!pointInInventoryPanelChild);
+ }
+
+ return handled;
+}
+
+BOOL LLFloaterOutbox::handleHover(S32 x, S32 y, MASK mask)
+{
+ mOutboxTopLevelDropZone->setBackgroundVisible(FALSE);
+
+ return LLFloater::handleHover(x, y, mask);
+}
+
+void LLFloaterOutbox::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mOutboxTopLevelDropZone->setBackgroundVisible(FALSE);
+
+ LLFloater::onMouseLeave(x, y, mask);
+}
+
+void LLFloaterOutbox::onImportButtonClicked()
+{
+ mOutboxInventoryPanel->clearSelection();
+
+ mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport();
+}
+
+void LLFloaterOutbox::onOutboxChanged()
+{
+ llassert(!mOutboxId.isNull());
+
+ if (mOutboxInventoryPanel)
+ {
+ mOutboxInventoryPanel->requestSort();
+ }
+
+ fetchOutboxContents();
+
+ updateView();
+}
+
+void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
+{
+ if (status == MarketplaceErrorCodes::IMPORT_DONE)
+ {
+ LLNotificationsUtil::add("OutboxImportComplete");
+ }
+ else if (status == MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS)
+ {
+ const LLSD& subs = getMarketplaceStringSubstitutions();
+
+ LLNotificationsUtil::add("OutboxImportHadErrors", subs);
+ }
+ else
+ {
+ char status_string[16];
+ sprintf(status_string, "%d", status);
+
+ LLSD subs;
+ subs["[ERROR_CODE]"] = status_string;
+
+ LLNotificationsUtil::add("OutboxImportFailed", subs);
+ }
+
+ updateView();
+}
+
+void LLFloaterOutbox::importStatusChanged(bool inProgress)
+{
+ if (inProgress)
+ {
+ if (mImportBusy)
+ {
+ setStatusString(getString("OutboxImporting"));
+ }
+ else
+ {
+ setStatusString(getString("OutboxInitializing"));
+ }
+
+ mImportBusy = true;
+ mImportButton->setEnabled(false);
+ mInventoryImportInProgress->setVisible(true);
+ }
+ else
+ {
+ mImportBusy = false;
+ mImportButton->setEnabled(mOutboxItemCount > 0);
+ mInventoryImportInProgress->setVisible(false);
+ }
+
+ updateView();
+}
+
+void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
+{
+ if (status != MarketplaceErrorCodes::IMPORT_DONE)
+ {
+ char status_string[16];
+ sprintf(status_string, "%d", status);
+
+ LLSD subs;
+ subs["[ERROR_CODE]"] = status_string;
+
+ LLNotificationsUtil::add("OutboxInitFailed", subs);
+ }
+
+ updateView();
+}
+
+void LLFloaterOutbox::showNotification(const LLSD& notify)
+{
+ LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
+
+ if (!notification)
+ {
+ llerrs << "Unable to find outbox notification!" << notify.asString() << llendl;
+
+ return;
+ }
+
+#if USE_WINDOWSHADE_DIALOGS
+
+ if (mWindowShade)
+ {
+ delete mWindowShade;
+ }
+
+ LLRect floater_rect = getLocalRect();
+ floater_rect.mTop -= getHeaderHeight();
+ floater_rect.stretch(-5, 0);
+
+ LLWindowShade::Params params;
+ params.name = "notification_shade";
+ params.rect = floater_rect;
+ params.follows.flags = FOLLOWS_ALL;
+ params.modal = true;
+ params.can_close = false;
+ params.shade_color = LLColor4::white % 0.25f;
+ params.text_color = LLColor4::white;
+
+ mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
+
+ addChild(mWindowShade);
+ mWindowShade->show(notification);
+
+#else
+
+ LLNotificationsUI::LLEventHandler * handler =
+ LLNotificationsUI::LLNotificationManager::instance().getHandlerForNotification("alertmodal");
+
+ LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler *>(handler);
+ llassert(sys_handler);
+
+ sys_handler->processNotification(notify);
+
+#endif
+}
+
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
new file mode 100644
index 0000000000..18baccf1c9
--- /dev/null
+++ b/indra/newview/llfloateroutbox.h
@@ -0,0 +1,114 @@
+/**
+ * @file llfloateroutbox.h
+ * @brief LLFloaterOutbox
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATEROUTBOX_H
+#define LL_LLFLOATEROUTBOX_H
+
+#include "llfloater.h"
+#include "llfoldertype.h"
+#include "llnotificationptr.h"
+
+
+class LLButton;
+class LLInventoryCategoriesObserver;
+class LLInventoryCategoryAddedObserver;
+class LLInventoryPanel;
+class LLLoadingIndicator;
+class LLNotification;
+class LLTextBox;
+class LLView;
+class LLWindowShade;
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFloaterOutbox
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFloaterOutbox : public LLFloater
+{
+public:
+ LLFloaterOutbox(const LLSD& key);
+ ~LLFloaterOutbox();
+
+ void setupOutbox(const LLUUID& outboxId);
+
+ // virtuals
+ BOOL postBuild();
+ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ void showNotification(const LLSD& notify);
+
+ BOOL handleHover(S32 x, S32 y, MASK mask);
+ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+protected:
+ void fetchOutboxContents();
+
+ void importReportResults(U32 status, const LLSD& content);
+ void importStatusChanged(bool inProgress);
+ void initializationReportError(U32 status, const LLSD& content);
+
+ void onClose(bool app_quitting);
+ void onOpen(const LLSD& key);
+
+ void onFocusReceived();
+
+ void onImportButtonClicked();
+ void onOutboxChanged();
+
+ void setStatusString(const std::string& statusString);
+
+ void updateFolderCount();
+ void updateFolderCountStatus();
+ void updateView();
+
+private:
+ LLInventoryCategoriesObserver * mCategoriesObserver;
+ LLInventoryCategoryAddedObserver * mCategoryAddedObserver;
+
+ bool mImportBusy;
+ LLButton * mImportButton;
+
+ LLTextBox * mInventoryFolderCountText;
+ LLView * mInventoryImportInProgress;
+ LLView * mInventoryPlaceholder;
+ LLTextBox * mInventoryText;
+ LLTextBox * mInventoryTitle;
+
+ LLUUID mOutboxId;
+ LLInventoryPanel * mOutboxInventoryPanel;
+ U32 mOutboxItemCount;
+ LLPanel * mOutboxTopLevelDropZone;
+
+ LLWindowShade * mWindowShade;
+};
+
+#endif // LL_LLFLOATEROUTBOX_H
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index cc7a1b2368..d8d62e5bbb 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -1489,6 +1489,12 @@ void LLFloaterSnapshot::Impl::setNeedRefresh(LLFloaterSnapshot* floater, bool ne
{
if (!floater) return;
+ // Don't display the "Refresh to save" message if we're in auto-refresh mode.
+ if (gSavedSettings.getBOOL("AutoSnapshot"))
+ {
+ need = false;
+ }
+
floater->mRefreshLabel->setVisible(need);
floater->impl.mNeedRefresh = need;
}
@@ -1984,7 +1990,7 @@ LLFloaterSnapshot::LLFloaterSnapshot(const LLSD& key)
// Destroys the object
LLFloaterSnapshot::~LLFloaterSnapshot()
{
- delete impl.mPreviewHandle.get();
+ if (impl.mPreviewHandle.get()) impl.mPreviewHandle.get()->die();
//unfreeze everything else
gSavedSettings.setBOOL("FreezeTime", FALSE);
@@ -2053,6 +2059,13 @@ BOOL LLFloaterSnapshot::postBuild()
gFloaterView->removeChild(this);
gSnapshotFloaterView->addChild(this);
+ // Pre-select "Current Window" resolution.
+ getChild<LLComboBox>("profile_size_combo")->selectNthItem(0);
+ getChild<LLComboBox>("postcard_size_combo")->selectNthItem(0);
+ getChild<LLComboBox>("texture_size_combo")->selectNthItem(0);
+ getChild<LLComboBox>("local_size_combo")->selectNthItem(0);
+ getChild<LLComboBox>("local_format_combo")->selectNthItem(0);
+
impl.mPreviewHandle = previewp->getHandle();
impl.updateControls(this);
impl.updateLayout(this);
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 1008b4a6e4..bd5b5f4eb0 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -529,7 +529,7 @@ void LLFloaterTools::refresh()
mPanelLandInfo->refresh();
// Refresh the advanced weights floater
- LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::getTypedInstance<LLFloaterObjectWeights>("object_weights");
+ LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::findTypedInstance<LLFloaterObjectWeights>("object_weights");
if(object_weights_floater && object_weights_floater->getVisible())
{
object_weights_floater->refresh();
@@ -1409,9 +1409,7 @@ bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& re
//
void LLFloaterTools::clearMediaSettings()
{
- LLFloaterMediaSettings::getInstance();
LLFloaterMediaSettings::clearValues(false);
-
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index 959edff713..428a02e9f0 100644
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -29,6 +29,7 @@
#include "llfloatertranslationsettings.h"
// Viewer includes
+#include "llnearbychatbar.h"
#include "lltranslate.h"
#include "llviewercontrol.h" // for gSavedSettings
@@ -292,5 +293,6 @@ void LLFloaterTranslationSettings::onBtnOK()
gSavedSettings.setString("TranslationService", getSelectedService());
gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
+ LLNearbyChatBar::getInstance()->enableTranslationCheckbox(LLTranslate::isTranslationConfigured());
closeFloater(false);
}
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 4c9c4cb154..d741b5b133 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -915,14 +915,16 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
{
panel->buildFromFile(path); // build it
LLRect new_size = panel->getRect(); // get its rectangle
- panel->setOrigin(0,0); // reset its origin point so it's not offset by -left or other XUI attributes
+ panel->setOrigin(2,2); // reset its origin point so it's not offset by -left or other XUI attributes
(*floaterp)->setTitle(path); // use the file name as its title, since panels have no guaranteed meaningful name attribute
panel->setUseBoundingRect(TRUE); // enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements)
panel->updateBoundingRect(); // update bounding rect
LLRect bounding_rect = panel->getBoundingRect(); // get the bounding rect
LLRect new_rect = panel->getRect(); // get the panel's rect
new_rect.unionWith(bounding_rect); // union them to make sure we get the biggest one possible
- (*floaterp)->reshape(new_rect.getWidth(), new_rect.getHeight() + floater_header_size); // reshape floater to match the union rect's dimensions
+ LLRect floater_rect = new_rect;
+ floater_rect.stretch(4, 4);
+ (*floaterp)->reshape(floater_rect.getWidth(), floater_rect.getHeight() + floater_header_size); // reshape floater to match the union rect's dimensions
panel->reshape(new_rect.getWidth(), new_rect.getHeight()); // reshape panel to match the union rect's dimensions as well (both are needed)
(*floaterp)->addChild(panel); // add panel as child
(*floaterp)->openFloater(); // open floater (needed?)
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 6ec2598e44..e0d7d67f7d 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -172,6 +172,7 @@ LLFolderView::Params::Params()
title("title"),
use_label_suffix("use_label_suffix"),
allow_multiselect("allow_multiselect", true),
+ show_empty_message("show_empty_message", true),
show_load_status("show_load_status", true),
use_ellipses("use_ellipses", false)
{
@@ -185,6 +186,7 @@ LLFolderView::LLFolderView(const Params& p)
mScrollContainer( NULL ),
mPopupMenuHandle(),
mAllowMultiSelect(p.allow_multiselect),
+ mShowEmptyMessage(p.show_empty_message),
mShowFolderHierarchy(FALSE),
mSourceID(p.task_id),
mRenameItem( NULL ),
@@ -299,7 +301,7 @@ LLFolderView::~LLFolderView( void )
mAutoOpenItems.removeAllNodes();
gIdleCallbacks.deleteFunction(idle, this);
- delete mPopupMenuHandle.get();
+ if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
mAutoOpenItems.removeAllNodes();
clearSelection();
@@ -349,10 +351,6 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
{
mFolders.insert(mFolders.begin(), folder);
}
- if (folder->numSelected())
- {
- recursiveIncrementNumDescendantsSelected(folder->numSelected());
- }
folder->setShowLoadStatus(mShowLoadStatus);
folder->setOrigin(0, 0);
folder->reshape(getRect().getWidth(), 0);
@@ -694,26 +692,6 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
return rv;
}
-void LLFolderView::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items)
-{
- // now store resulting selection
- if (mAllowMultiSelect)
- {
- LLFolderViewItem *cur_selection = getCurSelectedItem();
- LLFolderViewFolder::extendSelection(selection, cur_selection, items);
- for (S32 i = 0; i < items.count(); i++)
- {
- addToSelectionList(items[i]);
- }
- }
- else
- {
- setSelection(selection, FALSE, FALSE);
- }
-
- mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS;
-}
-
static LLFastTimer::DeclareTimer FTM_SANITIZE_SELECTION("Sanitize Selection");
void LLFolderView::sanitizeSelection()
{
@@ -932,7 +910,7 @@ void LLFolderView::draw()
mStatusText.clear();
mStatusTextBox->setVisible( FALSE );
}
- else
+ else if (mShowEmptyMessage)
{
if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
{
@@ -966,7 +944,6 @@ void LLFolderView::draw()
// See EXT-7564, EXT-7047.
arrangeFromRoot();
}
-
}
// skip over LLFolderViewFolder::draw since we don't want the folder icon, label,
@@ -1058,7 +1035,7 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
{
item = *item_it;
- if(item->isRemovable())
+ if (item && item->isRemovable())
{
items.push_back(item);
}
@@ -1222,7 +1199,9 @@ void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_f
void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
{
- if (mAutoOpenItems.check() == item || mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH)
+ if ((mAutoOpenItems.check() == item) ||
+ (mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) ||
+ item->isOpen())
{
return;
}
@@ -1945,9 +1924,9 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
if (!handled)
{
if (getListener()->getUUID().notNull())
- {
- handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
- }
+ {
+ handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ }
else
{
if (!mFolders.empty())
@@ -1969,7 +1948,7 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFolderView::deleteAllChildren()
{
closeRenamer();
- delete mPopupMenuHandle.get();
+ if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
mPopupMenuHandle = LLHandle<LLView>();
mScrollContainer = NULL;
mRenameItem = NULL;
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 8af01e9102..1d018b5e6a 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -75,6 +75,7 @@ public:
Optional<std::string> title;
Optional<bool> use_label_suffix,
allow_multiselect,
+ show_empty_message,
show_load_status,
use_ellipses;
@@ -106,6 +107,8 @@ public:
U32 getSortOrder() const;
BOOL isFilterModified();
+ bool getAllowMultiSelect() { return mAllowMultiSelect; }
+
// Close all folders in the view
void closeAllFolders();
void openTopLevelFolders();
@@ -141,8 +144,6 @@ public:
// children, and keeps track of selected objects.
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
- virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items);
-
virtual std::set<LLUUID> getSelectionList() const;
// make sure if ancestor is selected, descendents are not
@@ -156,7 +157,6 @@ public:
void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
-
// deletion functionality
void removeSelectedItems();
@@ -282,6 +282,7 @@ protected:
selected_items_t mSelectedItems;
BOOL mKeyboardSelection;
BOOL mAllowMultiSelect;
+ BOOL mShowEmptyMessage;
BOOL mShowFolderHierarchy;
LLUUID mSourceID;
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index f27fd035db..8d6114c887 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -386,13 +386,6 @@ void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL
getRoot()->changeSelection(selection, selected);
}
-void LLFolderViewItem::extendSelectionFromRoot(LLFolderViewItem* selection)
-{
- LLDynamicArray<LLFolderViewItem*> selected_items;
-
- getRoot()->extendSelection(selection, NULL, selected_items);
-}
-
std::set<LLUUID> LLFolderViewItem::getSelectionList() const
{
std::set<LLUUID> selection;
@@ -496,10 +489,6 @@ BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem,
if (selection == this && !mIsSelected)
{
selectItem();
- if (mListener)
- {
- mListener->selectItem();
- }
}
else if (mIsSelected) // Deselect everything else.
{
@@ -510,7 +499,7 @@ BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem,
BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
{
- if (selection == this && mIsSelected != selected)
+ if (selection == this)
{
if (mIsSelected)
{
@@ -520,10 +509,6 @@ BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selecte
{
selectItem();
}
- if (mListener)
- {
- mListener->selectItem();
- }
return TRUE;
}
return FALSE;
@@ -531,29 +516,18 @@ BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selecte
void LLFolderViewItem::deselectItem(void)
{
- llassert(mIsSelected);
-
mIsSelected = FALSE;
-
- // Update ancestors' count of selected descendents.
- LLFolderViewFolder* parent_folder = getParentFolder();
- if (parent_folder)
- {
- parent_folder->recursiveIncrementNumDescendantsSelected(-1);
- }
}
void LLFolderViewItem::selectItem(void)
{
- llassert(!mIsSelected);
-
- mIsSelected = TRUE;
-
- // Update ancestors' count of selected descendents.
- LLFolderViewFolder* parent_folder = getParentFolder();
- if (parent_folder)
+ if (mIsSelected == FALSE)
{
- parent_folder->recursiveIncrementNumDescendantsSelected(1);
+ if (mListener)
+ {
+ mListener->selectItem();
+ }
+ mIsSelected = TRUE;
}
}
@@ -697,7 +671,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
}
else if (mask & MASK_SHIFT)
{
- extendSelectionFromRoot(this);
+ getParentFolder()->extendSelectionTo(this);
}
else
{
@@ -812,7 +786,7 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
}
else if (mask & MASK_SHIFT)
{
- extendSelectionFromRoot(this);
+ getParentFolder()->extendSelectionTo(this);
}
else
{
@@ -1125,7 +1099,6 @@ void LLFolderViewItem::draw()
LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
LLFolderViewItem( p ), // 0 = no create time
- mNumDescendantsSelected(0),
mIsOpen(FALSE),
mExpanderHighlighted(FALSE),
mCurHeight(0.f),
@@ -1572,21 +1545,6 @@ BOOL LLFolderViewFolder::hasFilteredDescendants()
return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration();
}
-void LLFolderViewFolder::recursiveIncrementNumDescendantsSelected(S32 increment)
-{
- LLFolderViewFolder* parent_folder = this;
- do
- {
- parent_folder->mNumDescendantsSelected += increment;
-
- // Make sure we don't have negative values.
- llassert(parent_folder->mNumDescendantsSelected >= 0);
-
- parent_folder = parent_folder->getParentFolder();
- }
- while(parent_folder);
-}
-
// Passes selection information on to children and record selection
// information if necessary.
BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
@@ -1599,10 +1557,6 @@ BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem
{
selectItem();
}
- if (mListener)
- {
- mListener->selectItem();
- }
rv = TRUE;
}
else
@@ -1663,10 +1617,6 @@ BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selec
deselectItem();
}
}
- if (mListener && selected)
- {
- mListener->selectItem();
- }
}
for (folders_t::iterator iter = mFolders.begin();
@@ -1690,119 +1640,261 @@ BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selec
return rv;
}
-void LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items)
+LLFolderViewFolder* LLFolderViewFolder::getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse)
{
- // pass on to child folders first
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
+ if (!item_a->getParentFolder() || !item_b->getParentFolder()) return NULL;
+
+ std::deque<LLFolderViewFolder*> item_a_ancestors;
+
+ LLFolderViewFolder* parent = item_a->getParentFolder();
+ while(parent)
{
- folders_t::iterator fit = iter++;
- (*fit)->extendSelection(selection, last_selected, selected_items);
+ item_a_ancestors.push_back(parent);
+ parent = parent->getParentFolder();
}
- // handle selection of our immediate children...
- BOOL reverse_select = FALSE;
- BOOL found_last_selected = FALSE;
- BOOL found_selection = FALSE;
- LLDynamicArray<LLFolderViewItem*> items_to_select;
- LLFolderViewItem* item;
+ std::deque<LLFolderViewFolder*> item_b_ancestors;
+
+ parent = item_b->getParentFolder();
+ while(parent)
+ {
+ item_b_ancestors.push_back(parent);
+ parent = parent->getParentFolder();
+ }
- //...folders first...
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
+ LLFolderViewFolder* common_ancestor = item_a->getRoot();
+
+ while(item_a_ancestors.size() > item_b_ancestors.size())
{
- folders_t::iterator fit = iter++;
- item = (*fit);
- if(item == selection)
- {
- found_selection = TRUE;
- }
- else if (item == last_selected)
+ item_a = item_a_ancestors.front();
+ item_a_ancestors.pop_front();
+ }
+
+ while(item_b_ancestors.size() > item_a_ancestors.size())
+ {
+ item_b = item_b_ancestors.front();
+ item_b_ancestors.pop_front();
+ }
+
+ while(item_a_ancestors.size())
+ {
+ common_ancestor = item_a_ancestors.front();
+
+ if (item_a_ancestors.front() == item_b_ancestors.front())
{
- found_last_selected = TRUE;
- if (found_selection)
+ // which came first, sibling a or sibling b?
+ for (folders_t::iterator it = common_ancestor->mFolders.begin(), end_it = common_ancestor->mFolders.end();
+ it != end_it;
+ ++it)
{
- reverse_select = TRUE;
+ LLFolderViewItem* item = *it;
+
+ if (item == item_a)
+ {
+ reverse = false;
+ return common_ancestor;
+ }
+ if (item == item_b)
+ {
+ reverse = true;
+ return common_ancestor;
+ }
}
- }
- if (found_selection || found_last_selected)
- {
- // deselect currently selected items so they can be pushed back on queue
- if (item->isSelected())
+ for (items_t::iterator it = common_ancestor->mItems.begin(), end_it = common_ancestor->mItems.end();
+ it != end_it;
+ ++it)
{
- item->changeSelection(item, FALSE);
+ LLFolderViewItem* item = *it;
+
+ if (item == item_a)
+ {
+ reverse = false;
+ return common_ancestor;
+ }
+ if (item == item_b)
+ {
+ reverse = true;
+ return common_ancestor;
+ }
}
- items_to_select.put(item);
+ break;
}
- if (found_selection && found_last_selected)
- {
- break;
- }
+ item_a = item_a_ancestors.front();
+ item_a_ancestors.pop_front();
+ item_b = item_b_ancestors.front();
+ item_b_ancestors.pop_front();
}
- if (!(found_selection && found_last_selected))
+ return NULL;
+}
+
+void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items)
+{
+ bool selecting = start == NULL;
+ if (reverse)
{
- //,,,then items
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
+ for (items_t::reverse_iterator it = mItems.rbegin(), end_it = mItems.rend();
+ it != end_it;
+ ++it)
{
- items_t::iterator iit = iter++;
- item = (*iit);
- if(item == selection)
+ if (*it == end)
{
- found_selection = TRUE;
+ return;
}
- else if (item == last_selected)
+ if (selecting)
{
- found_last_selected = TRUE;
- if (found_selection)
- {
- reverse_select = TRUE;
- }
+ items.push_back(*it);
}
- if (found_selection || found_last_selected)
+ if (*it == start)
{
- // deselect currently selected items so they can be pushed back on queue
- if (item->isSelected())
- {
- item->changeSelection(item, FALSE);
- }
- items_to_select.put(item);
+ selecting = true;
+ }
+ }
+ for (folders_t::reverse_iterator it = mFolders.rbegin(), end_it = mFolders.rend();
+ it != end_it;
+ ++it)
+ {
+ if (*it == end)
+ {
+ return;
}
- if (found_selection && found_last_selected)
+ if (selecting)
{
- break;
+ items.push_back(*it);
+ }
+
+ if (*it == start)
+ {
+ selecting = true;
}
}
}
-
- if (found_last_selected && found_selection)
+ else
{
- // we have a complete selection inside this folder
- for (S32 index = reverse_select ? items_to_select.getLength() - 1 : 0;
- reverse_select ? index >= 0 : index < items_to_select.getLength(); reverse_select ? index-- : index++)
+ for (folders_t::iterator it = mFolders.begin(), end_it = mFolders.end();
+ it != end_it;
+ ++it)
{
- LLFolderViewItem* item = items_to_select[index];
- if (item->changeSelection(item, TRUE))
+ if (*it == end)
{
- selected_items.put(item);
+ return;
+ }
+
+ if (selecting)
+ {
+ items.push_back(*it);
+ }
+
+ if (*it == start)
+ {
+ selecting = true;
+ }
+ }
+ for (items_t::iterator it = mItems.begin(), end_it = mItems.end();
+ it != end_it;
+ ++it)
+ {
+ if (*it == end)
+ {
+ return;
+ }
+
+ if (selecting)
+ {
+ items.push_back(*it);
+ }
+
+ if (*it == start)
+ {
+ selecting = true;
}
}
}
- else if (found_selection)
+}
+
+void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
+{
+ if (getRoot()->getAllowMultiSelect() == FALSE) return;
+
+ LLFolderViewItem* cur_selected_item = getRoot()->getCurSelectedItem();
+ if (cur_selected_item == NULL)
{
- // last selection was not in this folder....go ahead and select just the new item
- if (selection->changeSelection(selection, TRUE))
+ cur_selected_item = new_selection;
+ }
+
+
+ bool reverse = false;
+ LLFolderViewFolder* common_ancestor = getCommonAncestor(cur_selected_item, new_selection, reverse);
+ if (!common_ancestor) return;
+
+ LLFolderViewItem* last_selected_item_from_cur = cur_selected_item;
+ LLFolderViewFolder* cur_folder = cur_selected_item->getParentFolder();
+
+ std::vector<LLFolderViewItem*> items_to_select_forward;
+
+ while(cur_folder != common_ancestor)
+ {
+ cur_folder->gatherChildRangeExclusive(last_selected_item_from_cur, NULL, reverse, items_to_select_forward);
+
+ last_selected_item_from_cur = cur_folder;
+ cur_folder = cur_folder->getParentFolder();
+ }
+
+ std::vector<LLFolderViewItem*> items_to_select_reverse;
+
+ LLFolderViewItem* last_selected_item_from_new = new_selection;
+ cur_folder = new_selection->getParentFolder();
+ while(cur_folder != common_ancestor)
+ {
+ cur_folder->gatherChildRangeExclusive(last_selected_item_from_new, NULL, !reverse, items_to_select_reverse);
+
+ last_selected_item_from_new = cur_folder;
+ cur_folder = cur_folder->getParentFolder();
+ }
+
+ common_ancestor->gatherChildRangeExclusive(last_selected_item_from_cur, last_selected_item_from_new, reverse, items_to_select_forward);
+
+ for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_reverse.rbegin(), end_it = items_to_select_reverse.rend();
+ it != end_it;
+ ++it)
+ {
+ items_to_select_forward.push_back(*it);
+ }
+
+ LLFolderView* root = getRoot();
+
+ for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end();
+ it != end_it;
+ ++it)
+ {
+ LLFolderViewItem* item = *it;
+ if (item->isSelected())
+ {
+ root->removeFromSelectionList(item);
+ }
+ else
{
- selected_items.put(selection);
+ item->selectItem();
}
+ root->addToSelectionList(item);
+ }
+
+ if (new_selection->isSelected())
+ {
+ root->removeFromSelectionList(new_selection);
+ }
+ else
+ {
+ new_selection->selectItem();
}
+ root->addToSelectionList(new_selection);
}
+
void LLFolderViewFolder::destroyView()
{
for (items_t::iterator iter = mItems.begin();
@@ -1874,19 +1966,11 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
ft = std::find(mFolders.begin(), mFolders.end(), f);
if (ft != mFolders.end())
{
- if ((*ft)->numSelected())
- {
- recursiveIncrementNumDescendantsSelected(-(*ft)->numSelected());
- }
mFolders.erase(ft);
}
}
else
{
- if ((*it)->isSelected())
- {
- recursiveIncrementNumDescendantsSelected(-1);
- }
mItems.erase(it);
}
//item has been removed, need to update filter
@@ -2055,11 +2139,6 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
{
mItems.push_back(item);
- if (item->isSelected())
- {
- recursiveIncrementNumDescendantsSelected(1);
- }
-
item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
item->setVisible(FALSE);
@@ -2067,8 +2146,14 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
item->dirtyFilter();
- // Update the folder creation date if the child is newer than our current date
- setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate()));
+ // Update the folder creation date if the folder has no creation date
+ bool setting_date = false;
+ const time_t item_creation_date = item->getCreationDate();
+ if ((item_creation_date > 0) && (mCreationDate == 0))
+ {
+ setCreationDate(item_creation_date);
+ setting_date = true;
+ }
// Handle sorting
requestArrange();
@@ -2078,8 +2163,11 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
LLFolderViewFolder* parentp = getParentFolder();
while (parentp)
{
- // Update the folder creation date if the child is newer than our current date
- parentp->setCreationDate(llmax<time_t>(parentp->mCreationDate, item->getCreationDate()));
+ // Update the parent folder creation date
+ if (setting_date && (parentp->mCreationDate == 0))
+ {
+ parentp->setCreationDate(item_creation_date);
+ }
if (parentp->mSortFunction.isByDate())
{
@@ -2097,10 +2185,6 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
{
mFolders.push_back(folder);
- if (folder->numSelected())
- {
- recursiveIncrementNumDescendantsSelected(folder->numSelected());
- }
folder->setOrigin(0, 0);
folder->reshape(getRect().getWidth(), 0);
folder->setVisible(FALSE);
@@ -2276,33 +2360,16 @@ BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
EAcceptance* accept,
std::string& tooltip_msg)
{
- LLFolderView* root_view = getRoot();
-
BOOL handled = FALSE;
- if(mIsOpen)
+
+ if (mIsOpen)
{
- handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
- cargo_data, accept, tooltip_msg) != NULL;
+ handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL);
}
if (!handled)
{
- BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data, tooltip_msg);
-
- if (accepted)
- {
- mDragAndDropTarget = TRUE;
- *accept = ACCEPT_YES_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
-
- if (!drop && accepted)
- {
- root_view->autoOpenTest(this);
- }
+ handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl;
}
@@ -2310,6 +2377,33 @@ BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
return TRUE;
}
+BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ BOOL accepted = mListener && mListener->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+
+ if (accepted)
+ {
+ mDragAndDropTarget = TRUE;
+ *accept = ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+
+ if (!drop && accepted)
+ {
+ getRoot()->autoOpenTest(this);
+ }
+
+ return TRUE;
+}
+
BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 3433e3f7f3..2fc79f5765 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -122,6 +122,8 @@ public:
// Mostly for debugging printout purposes.
const std::string& getSearchableLabel() { return mSearchableLabel; }
+
+ BOOL isLoading() const { return mIsLoading; }
private:
BOOL mIsSelected;
@@ -164,9 +166,6 @@ protected:
// helper function to change the selection from the root.
void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
- // helper function to change the selection from the root.
- void extendSelectionFromRoot(LLFolderViewItem* selection);
-
// this is an internal method used for adding items to folders. A
// no-op at this level, but reimplemented in derived classes.
virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
@@ -224,9 +223,6 @@ public:
// Returns TRUE if the selection state of this item was changed.
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
- // this method is used to group select items
- virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items) { }
-
// this method is used to deselect this element
void deselectItem();
@@ -373,13 +369,6 @@ public:
typedef std::list<LLFolderViewItem*> items_t;
typedef std::list<LLFolderViewFolder*> folders_t;
-private:
- S32 mNumDescendantsSelected;
-
-public: // Accessed needed by LLFolderViewItem
- void recursiveIncrementNumDescendantsSelected(S32 increment);
- S32 numSelected(void) const { return mNumDescendantsSelected + (isSelected() ? 1 : 0); }
-
protected:
items_t mItems;
folders_t mFolders;
@@ -461,7 +450,7 @@ public:
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
// this method is used to group select items
- virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items);
+ void extendSelectionTo(LLFolderViewItem* selection);
// Returns true is this object and all of its children can be removed.
virtual BOOL isRemovable();
@@ -547,11 +536,15 @@ public:
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
+ BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
virtual void draw();
time_t getCreationDate() const;
bool isTrash() const;
- S32 getNumSelectedDescendants(void) const { return mNumDescendantsSelected; }
folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); }
folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); }
@@ -560,6 +553,8 @@ public:
items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
items_t::const_iterator getItemsEnd() const { return mItems.end(); }
items_t::size_type getItemsCount() const { return mItems.size(); }
+ LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
+ void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items);
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index f7ed1116cb..bbf66ca750 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -95,7 +95,7 @@ LLGroupList::LLGroupList(const Params& p)
LLGroupList::~LLGroupList()
{
gAgent.removeListener(this);
- delete mContextMenuHandle.get();
+ if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
}
// virtual
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index f5cda52d44..f67464078b 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -234,12 +234,6 @@ LLIMFloater::~LLIMFloater()
//virtual
BOOL LLIMFloater::postBuild()
{
- // User-resizable control panels in P2P sessions look ugly (EXT-3470).
- if (mDialog == IM_NOTHING_SPECIAL || mDialog == IM_SESSION_P2P_INVITE)
- {
- getChild<LLLayoutStack>("im_panels")->setPanelUserResize("panel_im_control_panel", FALSE);
- }
-
const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
if (other_party_id.notNull())
{
@@ -385,9 +379,6 @@ void LLIMFloater::onSlide()
getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getParent()->getVisible());
getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getParent()->getVisible());
-
- LLLayoutStack* stack = getChild<LLLayoutStack>("im_panels");
- if (stack) stack->setAnimate(true);
}
//static
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
index bf6cf52298..a12ec390af 100644
--- a/indra/newview/llinspectremoteobject.cpp
+++ b/indra/newview/llinspectremoteobject.cpp
@@ -60,12 +60,10 @@ public:
private:
void update();
- void onNameCache(const LLUUID& id, const std::string& name, bool is_group);
private:
LLUUID mObjectID;
LLUUID mOwnerID;
- std::string mOwnerLegacyName;
std::string mSLurl;
std::string mName;
bool mGroupOwned;
@@ -75,7 +73,6 @@ LLInspectRemoteObject::LLInspectRemoteObject(const LLSD& sd) :
LLInspect(LLSD()),
mObjectID(NULL),
mOwnerID(NULL),
- mOwnerLegacyName(),
mSLurl(""),
mName(""),
mGroupOwned(false)
@@ -111,14 +108,6 @@ void LLInspectRemoteObject::onOpen(const LLSD& data)
mGroupOwned = data["group_owned"].asBoolean();
mSLurl = data["slurl"].asString();
- // work out the owner's name
- mOwnerLegacyName = "";
- if (gCacheName)
- {
- gCacheName->get(mOwnerID, mGroupOwned, // muting
- boost::bind(&LLInspectRemoteObject::onNameCache, this, _1, _2, _3));
- }
-
// update the inspector with the current object state
update();
@@ -144,8 +133,7 @@ void LLInspectRemoteObject::onClickMap()
void LLInspectRemoteObject::onClickBlock()
{
- LLMute::EType mute_type = mGroupOwned ? LLMute::GROUP : LLMute::AGENT;
- LLMute mute(mOwnerID, mOwnerLegacyName, mute_type);
+ LLMute mute(mObjectID, mName, LLMute::OBJECT);
LLMuteList::getInstance()->add(mute);
LLPanelBlockedList::showPanelAndSelect(mute.mID);
closeFloater();
@@ -156,12 +144,6 @@ void LLInspectRemoteObject::onClickClose()
closeFloater();
}
-void LLInspectRemoteObject::onNameCache(const LLUUID& id, const std::string& name, bool is_group)
-{
- mOwnerLegacyName = name;
- update();
-}
-
void LLInspectRemoteObject::update()
{
// show the object name as the inspector's title
@@ -198,8 +180,8 @@ void LLInspectRemoteObject::update()
// disable the Map button if we don't have a SLurl
getChild<LLUICtrl>("map_btn")->setEnabled(! mSLurl.empty());
- // disable the Block button if we don't have the owner ID
- getChild<LLUICtrl>("block_btn")->setEnabled(! mOwnerID.isNull());
+ // disable the Block button if we don't have the object ID (will this ever happen?)
+ getChild<LLUICtrl>("block_btn")->setEnabled(! mObjectID.isNull());
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 0c092e9a56..cebe93f042 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -53,6 +53,7 @@
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventorypanel.h"
+#include "llmarketplacefunctions.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llpreviewanim.h"
@@ -60,6 +61,7 @@
#include "llpreviewtexture.h"
#include "llselectmgr.h"
#include "llsidepanelappearance.h"
+#include "lltooldraganddrop.h"
#include "lltrans.h"
#include "llviewerassettype.h"
#include "llviewerfoldertype.h"
@@ -71,7 +73,9 @@
#include "llwearablelist.h"
// Marketplace outbox current disabled
-#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 0 // keep in sync with ENABLE_INVENTORY_DISPLAY_OUTBOX, ENABLE_MERCHANT_OUTBOX_PANEL
+#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 0
+#define ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU 0
+#define BLOCK_WORN_ITEMS_IN_OUTBOX 1
typedef std::pair<LLUUID, LLUUID> two_uuids_t;
typedef std::list<two_uuids_t> two_uuids_list_t;
@@ -127,6 +131,11 @@ bool isMarketplaceCopyAction(const std::string& action)
return (("copy_to_outbox" == action) || ("move_to_outbox" == action));
}
+bool isMarketplaceSendAction(const std::string& action)
+{
+ return ("send_to_marketplace" == action);
+}
+
// +=================================================+
// | LLInvFVBridge |
// +=================================================+
@@ -462,14 +471,13 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const
void hide_context_entries(LLMenuGL& menu,
const menuentry_vec_t &entries_to_show,
- const menuentry_vec_t &disabled_entries,
- BOOL append) // If append is TRUE, then new enabled entries
+ const menuentry_vec_t &disabled_entries)
{
const LLView::child_list_t *list = menu.getChildList();
// For removing double separators or leading separator. Start at true so that
// if the first element is a separator, it will not be shown.
- BOOL is_previous_entry_separator = TRUE;
+ bool is_previous_entry_separator = true;
for (LLView::child_list_t::const_iterator itor = list->begin();
itor != list->end();
@@ -485,7 +493,6 @@ void hide_context_entries(LLMenuGL& menu,
hide_context_entries(*branchp->getBranch(), entries_to_show, disabled_entries);
}
-
bool found = false;
menuentry_vec_t::const_iterator itor2;
for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2)
@@ -493,6 +500,7 @@ void hide_context_entries(LLMenuGL& menu,
if (*itor2 == name)
{
found = true;
+ break;
}
}
@@ -500,9 +508,8 @@ void hide_context_entries(LLMenuGL& menu,
// between two separators).
if (found)
{
- const BOOL is_entry_separator = (dynamic_cast<LLMenuItemSeparatorGL *>(menu_item) != NULL);
- if (is_entry_separator && is_previous_entry_separator)
- found = false;
+ const bool is_entry_separator = (dynamic_cast<LLMenuItemSeparatorGL *>(menu_item) != NULL);
+ found = !(is_entry_separator && is_previous_entry_separator);
is_previous_entry_separator = is_entry_separator;
}
@@ -512,6 +519,7 @@ void hide_context_entries(LLMenuGL& menu,
{
menu_item->setVisible(FALSE);
}
+
menu_item->setEnabled(FALSE);
}
else
@@ -520,17 +528,14 @@ void hide_context_entries(LLMenuGL& menu,
// A bit of a hack so we can remember that some UI element explicitly set this to be visible
// so that some other UI element from multi-select doesn't later set this invisible.
menu_item->pushVisible(TRUE);
- if (append)
- {
- menu_item->setEnabled(TRUE);
- }
- for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2)
+
+ bool enabled = (menu_item->getEnabled() == TRUE);
+ for (itor2 = disabled_entries.begin(); enabled && (itor2 != disabled_entries.end()); ++itor2)
{
- if (*itor2 == name)
- {
- menu_item->setEnabled(FALSE);
- }
+ enabled &= (*itor2 != name);
}
+
+ menu_item->setEnabled(enabled);
}
}
}
@@ -598,25 +603,16 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
{
items.push_back(std::string("Marketplace Separator"));
- bool copyable = true;
- LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID);
- if (inv_item)
- {
- copyable = inv_item->getPermissions().allowCopyBy(gAgent.getID());
- }
-
- const std::string merchant_action = ((copyable == true) ? "Merchant Copy" : "Merchant Move");
- items.push_back(merchant_action);
-
+ items.push_back(std::string("Merchant Copy"));
if (!canListOnMarketplaceNow())
{
- disabled_items.push_back(merchant_action);
+ disabled_items.push_back(std::string("Merchant Copy"));
}
}
}
}
- // Don't allow items to be pasted directly into the COF or the inbox
+ // Don't allow items to be pasted directly into the COF or the inbox/outbox
if (!isCOFFolder() && !isInboxFolder() && !isOutboxFolder())
{
items.push_back(std::string("Paste"));
@@ -657,7 +653,7 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else if(isOutboxFolder())
{
- items.push_back(std::string("Delete"));
+ addOutboxContextMenuOptions(flags, items, disabled_items);
}
else
{
@@ -734,6 +730,32 @@ void LLInvFVBridge::addOpenRightClickMenuOption(menuentry_vec_t &items)
items.push_back(std::string("Open"));
}
+void LLInvFVBridge::addOutboxContextMenuOptions(U32 flags,
+ menuentry_vec_t &items,
+ menuentry_vec_t &disabled_items)
+{
+ items.push_back(std::string("Rename"));
+ items.push_back(std::string("Delete"));
+
+ if ((flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Rename"));
+ }
+
+#if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
+ if (isOutboxFolderDirectParent())
+ {
+ items.push_back(std::string("Marketplace Separator"));
+ items.push_back(std::string("Marketplace Send"));
+
+ if ((flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Marketplace Send"));
+ }
+ }
+#endif // ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
+}
+
// *TODO: remove this
BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
{
@@ -854,6 +876,22 @@ BOOL LLInvFVBridge::isOutboxFolder() const
return gInventory.isObjectDescendentOf(mUUID, outbox_id);
}
+BOOL LLInvFVBridge::isOutboxFolderDirectParent() const
+{
+ BOOL outbox_is_parent = FALSE;
+
+ const LLInventoryCategory *cat = gInventory.getCategory(mUUID);
+
+ if (cat)
+ {
+ const LLUUID outbox_id = getOutboxFolder();
+
+ outbox_is_parent = (outbox_id.notNull() && (outbox_id == cat->getParentUUID()));
+ }
+
+ return outbox_is_parent;
+}
+
const LLUUID LLInvFVBridge::getOutboxFolder() const
{
const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
@@ -1040,82 +1078,134 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
}
}
-BOOL LLInvFVBridge::canShare() const
+bool LLInvFVBridge::canShare() const
{
- if (!isAgentInventory()) return FALSE;
+ bool can_share = false;
- const LLInventoryModel* model = getInventoryModel();
- if (!model) return FALSE;
-
- const LLViewerInventoryItem *item = model->getItem(mUUID);
- if (item)
+ if (isAgentInventory())
{
- if (!LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item))
- return FALSE;
- return (BOOL)LLGiveInventory::isInventoryGiveAcceptable(item);
+ const LLInventoryModel* model = getInventoryModel();
+ if (model)
+ {
+ const LLViewerInventoryItem *item = model->getItem(mUUID);
+ if (item)
+ {
+ if (LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item))
+ {
+ can_share = LLGiveInventory::isInventoryGiveAcceptable(item);
+ }
+ }
+ else
+ {
+ // Categories can be given.
+ can_share = (model->getCategory(mUUID) != NULL);
+ }
+ }
}
- // Categories can be given.
- if (model->getCategory(mUUID)) return TRUE;
-
- return FALSE;
+ return can_share;
}
-BOOL LLInvFVBridge::canListOnMarketplace() const
+bool LLInvFVBridge::canListOnMarketplace() const
{
#if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
+
LLInventoryModel * model = getInventoryModel();
+
const LLViewerInventoryCategory * cat = model->getCategory(mUUID);
if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
{
- return FALSE;
+ return false;
}
if (!isAgentInventory())
{
- return FALSE;
+ return false;
}
if (getOutboxFolder().isNull())
{
- return FALSE;
+ return false;
}
if (isInboxFolder() || isOutboxFolder())
{
- return FALSE;
+ return false;
}
-
+
LLViewerInventoryItem * item = model->getItem(mUUID);
- if (item && !item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ if (item)
{
- return FALSE;
+ if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ {
+ return false;
+ }
+
+ if (LLAssetType::AT_CALLINGCARD == item->getType())
+ {
+ return false;
+ }
}
- return TRUE;
+ return true;
+
#else
- return FALSE;
+ return false;
#endif
}
-BOOL LLInvFVBridge::canListOnMarketplaceNow() const
+bool LLInvFVBridge::canListOnMarketplaceNow() const
{
#if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
- if (get_is_item_worn(mUUID))
+
+ bool can_list = true;
+
+ // Do not allow listing while import is in progress
+ if (LLMarketplaceInventoryImporter::instanceExists())
{
- return FALSE;
+ can_list = !LLMarketplaceInventoryImporter::instance().isImportInProgress();
}
+
+ const LLInventoryObject* obj = getInventoryObject();
+ can_list &= (obj != NULL);
- // Loop through all items worn by avatar and check to see if they are descendants
- // of the item we are trying to list on the marketplace
- if (get_is_parent_to_worn_item(mUUID))
+ if (can_list)
{
- return FALSE;
+ const LLUUID& object_id = obj->getLinkedUUID();
+ can_list = object_id.notNull();
+
+ if (can_list)
+ {
+ LLFolderViewFolder * object_folderp = mRoot->getFolderByID(object_id);
+ if (object_folderp)
+ {
+ can_list = !object_folderp->isLoading();
+ }
+ }
+
+ if (can_list)
+ {
+ // Get outbox id
+ const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
+ LLFolderViewItem * outbox_itemp = mRoot->getItemByID(outbox_id);
+
+ if (outbox_itemp)
+ {
+ MASK mask = 0x0;
+ BOOL drop = FALSE;
+ EDragAndDropType cargo_type = LLViewerAssetType::lookupDragAndDropType(obj->getActualType());
+ void * cargo_data = (void *) obj;
+ std::string tooltip_msg;
+
+ can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+ }
+ }
}
+
+ return can_list;
- return TRUE;
#else
- return FALSE;
+ return false;
#endif
}
@@ -1225,7 +1315,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
if (!itemp) return;
const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
- copy_item_to_outbox(itemp, outbox_id, LLUUID::null);
+ copy_item_to_outbox(itemp, outbox_id, LLUUID::null, LLToolDragAndDrop::getOperationId());
}
}
@@ -1235,6 +1325,7 @@ void LLItemBridge::selectItem()
if(item && !item->isFinished())
{
item->fetchFromServer();
+ //LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false);
}
}
@@ -1564,11 +1655,7 @@ BOOL LLItemBridge::isItemCopyable() const
return FALSE;
}
- // All items can be copied in god mode since you can
- // at least paste-as-link the item, though you
- // still may not be able paste the item.
- return TRUE;
- // return (item->getPermissions().allowCopyBy(gAgent.getID()));
+ return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking");
}
return FALSE;
}
@@ -1681,12 +1768,8 @@ BOOL LLFolderBridge::isUpToDate() const
BOOL LLFolderBridge::isItemCopyable() const
{
- if (gSavedSettings.getBOOL("InventoryLinking"))
- {
- // Can copy folders to paste-as-link, but not for straight paste.
- return TRUE;
- }
- return FALSE;
+ // Can copy folders to paste-as-link, but not for straight paste.
+ return gSavedSettings.getBOOL("InventoryLinking");
}
BOOL LLFolderBridge::copyToClipboard() const
@@ -1787,30 +1870,41 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const
static BOOL can_move_to_outbox(LLInventoryItem* inv_item, std::string& tooltip_msg)
{
- bool worn = get_is_item_worn(inv_item->getUUID());
+ // Collapse links directly to items/folders
+ LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item;
+ LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem();
+ if (linked_item != NULL)
+ {
+ inv_item = linked_item;
+ }
+
bool allow_transfer = inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
-
if (!allow_transfer)
{
tooltip_msg = LLTrans::getString("TooltipOutboxNoTransfer");
+ return false;
}
- else if(worn)
+
+#if BLOCK_WORN_ITEMS_IN_OUTBOX
+ bool worn = get_is_item_worn(inv_item->getUUID());
+ if (worn)
{
tooltip_msg = LLTrans::getString("TooltipOutboxWorn");
+ return false;
}
+#endif
- return !worn && allow_transfer;
-}
-
-
-
-void LLFolderBridge::dropFolderToOutbox(LLInventoryCategory* inv_cat)
-{
- copy_folder_to_outbox(inv_cat, getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false), inv_cat->getUUID());
+ bool calling_card = (LLAssetType::AT_CALLINGCARD == inv_item->getType());
+ if (calling_card)
+ {
+ tooltip_msg = LLTrans::getString("TooltipOutboxCallingCard");
+ return false;
+ }
+
+ return true;
}
-
int get_folder_levels(LLInventoryCategory* inv_cat)
{
LLInventoryModel::cat_array_t* cats;
@@ -1865,54 +1959,78 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
if (!isAgentAvatarValid()) return FALSE;
if (!isAgentInventory()) return FALSE; // cannot drag categories into library
+ const LLUUID &cat_id = inv_cat->getUUID();
+ const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
+ const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
+
+ const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
+ const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id);
+ const BOOL move_is_from_outbox = model->isObjectDescendentOf(cat_id, outbox_id);
// check to make sure source is agent inventory, and is represented there.
LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
- const BOOL is_agent_inventory = (model->getCategory(inv_cat->getUUID()) != NULL)
+ const BOOL is_agent_inventory = (model->getCategory(cat_id) != NULL)
&& (LLToolDragAndDrop::SOURCE_AGENT == source);
- const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
- const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
-
BOOL accept = FALSE;
if (is_agent_inventory)
{
- const LLUUID &cat_id = inv_cat->getUUID();
const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false);
const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
- const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
const BOOL move_is_into_outfit = getCategory() && (getCategory()->getPreferredType() == LLFolderType::FT_OUTFIT);
const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id);
- const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id);
- const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_cat->getUUID(), outbox_id);
//--------------------------------------------------------------------------------
// Determine if folder can be moved.
//
BOOL is_movable = TRUE;
- if (LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
+
+ if (is_movable && (mUUID == cat_id))
+ {
+ is_movable = FALSE;
+ tooltip_msg = LLTrans::getString("TooltipDragOntoSelf");
+ }
+ if (is_movable && (model->isObjectDescendentOf(mUUID, cat_id)))
+ {
+ is_movable = FALSE;
+ tooltip_msg = LLTrans::getString("TooltipDragOntoOwnChild");
+ }
+ if (is_movable && LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
+ {
is_movable = FALSE;
- if (move_is_into_outfit)
+ // tooltip?
+ }
+ if (is_movable && move_is_into_outfit)
+ {
is_movable = FALSE;
- if (mUUID == gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE))
+ // tooltip?
+ }
+ if (is_movable && (mUUID == model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE)))
+ {
is_movable = FALSE;
+ // tooltip?
+ }
+
LLInventoryModel::cat_array_t descendent_categories;
LLInventoryModel::item_array_t descendent_items;
- gInventory.collectDescendents(cat_id, descendent_categories, descendent_items, FALSE);
- for (S32 i=0; i < descendent_categories.count(); ++i)
+ if (is_movable)
{
- LLInventoryCategory* category = descendent_categories[i];
- if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
+ model->collectDescendents(cat_id, descendent_categories, descendent_items, FALSE);
+ for (S32 i=0; i < descendent_categories.count(); ++i)
{
- // Can't move "special folders" (e.g. Textures Folder).
- is_movable = FALSE;
- break;
+ LLInventoryCategory* category = descendent_categories[i];
+ if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
+ {
+ // Can't move "special folders" (e.g. Textures Folder).
+ is_movable = FALSE;
+ break;
+ }
}
}
- if (move_is_into_trash)
+ if (is_movable && move_is_into_trash)
{
for (S32 i=0; i < descendent_items.count(); ++i)
{
@@ -1924,7 +2042,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
}
}
- if (move_is_into_landmarks)
+ if (is_movable && move_is_into_landmarks)
{
for (S32 i=0; i < descendent_items.count(); ++i)
{
@@ -1939,35 +2057,100 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
}
}
- if (move_is_into_outbox)
+ if (is_movable && move_is_into_outbox)
{
- for (S32 i=0; i < descendent_items.count(); ++i)
+ const int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat);
+
+ if (nested_folder_levels > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"))
{
- LLInventoryItem* item = descendent_items[i];
- if (!can_move_to_outbox(item, tooltip_msg))
- {
- is_movable = FALSE;
- break;
- }
+ tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels");
+ is_movable = FALSE;
}
+ else
+ {
+ int dragged_folder_count = descendent_categories.count();
+ int existing_item_count = 0;
+ int existing_folder_count = 0;
+
+ const LLViewerInventoryCategory * master_folder = model->getFirstDescendantOf(outbox_id, mUUID);
+
+ if (master_folder != NULL)
+ {
+ if (model->isObjectDescendentOf(cat_id, master_folder->getUUID()))
+ {
+ // Don't use count because we're already inside the same category anyway
+ dragged_folder_count = 0;
+ }
+ else
+ {
+ existing_folder_count = 1; // Include the master folder in the count!
+
+ // If we're in the drop operation as opposed to the drag without drop, we are doing a
+ // single category at a time so don't block based on the total amount of cargo data items
+ if (drop)
+ {
+ dragged_folder_count += 1;
+ }
+ else
+ {
+ // NOTE: The cargo id's count is a total of categories AND items but we err on the side of
+ // prevention rather than letting too many folders into the hierarchy of the outbox,
+ // when we're dragging the item to a new parent
+ dragged_folder_count += LLToolDragAndDrop::instance().getCargoIDsCount();
+ }
+ }
+
+ // Tally the total number of categories and items inside the master folder
- int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat);
+ LLInventoryModel::cat_array_t existing_categories;
+ LLInventoryModel::item_array_t existing_items;
- if (nested_folder_levels > 4)
- {
- tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels");
- is_movable = FALSE;
+ model->collectDescendents(master_folder->getUUID(), existing_categories, existing_items, FALSE);
+
+ existing_folder_count += existing_categories.count();
+ existing_item_count += existing_items.count();
+ }
+ else
+ {
+ // Assume a single category is being dragged to the outbox since we evaluate one at a time
+ // when not putting them under a parent item.
+ dragged_folder_count += 1;
+ }
+
+ const int nested_folder_count = existing_folder_count + dragged_folder_count;
+ const int nested_item_count = existing_item_count + descendent_items.count();
+
+ if (nested_folder_count > gSavedSettings.getU32("InventoryOutboxMaxFolderCount"))
+ {
+ tooltip_msg = LLTrans::getString("TooltipOutboxTooManyFolders");
+ is_movable = FALSE;
+ }
+ else if (nested_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount"))
+ {
+ tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects");
+ is_movable = FALSE;
+ }
+
+ if (is_movable == TRUE)
+ {
+ for (S32 i=0; i < descendent_items.count(); ++i)
+ {
+ LLInventoryItem* item = descendent_items[i];
+ if (!can_move_to_outbox(item, tooltip_msg))
+ {
+ is_movable = FALSE;
+ break;
+ }
+ }
+ }
}
-
}
//
//--------------------------------------------------------------------------------
- accept = is_movable
- && (mUUID != cat_id) // Can't move a folder into itself
- && (mUUID != inv_cat->getParentUUID()) // Avoid moves that would change nothing
- && !(model->isObjectDescendentOf(mUUID, cat_id)); // Avoid circularity
+ accept = is_movable;
+
if (accept && drop)
{
// Look for any gestures and deactivate them
@@ -1999,7 +2182,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
// Recursively create links in target outfit.
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
- gInventory.collectDescendents(inv_cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH);
+ model->collectDescendents(cat_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
LLAppearanceMgr::instance().linkAll(mUUID,items,NULL);
}
}
@@ -2017,7 +2200,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
const std::string empty_description = "";
link_inventory_item(
gAgent.getID(),
- inv_cat->getUUID(),
+ cat_id,
mUUID,
inv_cat->getName(),
empty_description,
@@ -2029,13 +2212,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
else if (move_is_into_outbox && !move_is_from_outbox)
{
- dropFolderToOutbox(inv_cat);
+ copy_folder_to_outbox(inv_cat, mUUID, cat_id, LLToolDragAndDrop::getOperationId());
}
else
{
- if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
+ if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
{
- set_dad_inbox_object(inv_cat->getUUID());
+ set_dad_inbox_object(cat_id);
}
// Reparent the folder and restamp children if it's moving
@@ -2050,15 +2233,28 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
else if (LLToolDragAndDrop::SOURCE_WORLD == source)
{
- // content category has same ID as object itself
- LLUUID object_id = inv_cat->getUUID();
- LLUUID category_id = mUUID;
- accept = move_inv_category_world_to_agent(object_id, category_id, drop);
+ if (move_is_into_outbox)
+ {
+ tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
+ accept = FALSE;
+ }
+ else
+ {
+ accept = move_inv_category_world_to_agent(cat_id, mUUID, drop);
+ }
}
else if (LLToolDragAndDrop::SOURCE_LIBRARY == source)
{
- // Accept folders that contain complete outfits.
- accept = move_is_into_current_outfit && LLAppearanceMgr::instance().getCanMakeFolderIntoOutfit(inv_cat->getUUID());
+ if (move_is_into_outbox)
+ {
+ tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
+ accept = FALSE;
+ }
+ else
+ {
+ // Accept folders that contain complete outfits.
+ accept = move_is_into_current_outfit && LLAppearanceMgr::instance().getCanMakeFolderIntoOutfit(cat_id);
+ }
if (accept && drop)
{
@@ -2201,7 +2397,6 @@ public:
delete this;
}
-
protected:
LLUUID mCatID;
bool mCopyItems;
@@ -2305,15 +2500,15 @@ void LLRightClickInventoryFetchDescendentsObserver::done()
class LLInventoryCopyAndWearObserver : public LLInventoryObserver
{
public:
- LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count) :
- mCatID(cat_id), mContentsCount(count), mFolderAdded(FALSE) {}
+ LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count, bool folder_added=false) :
+ mCatID(cat_id), mContentsCount(count), mFolderAdded(folder_added) {}
virtual ~LLInventoryCopyAndWearObserver() {}
virtual void changed(U32 mask);
protected:
LLUUID mCatID;
int mContentsCount;
- BOOL mFolderAdded;
+ bool mFolderAdded;
};
@@ -2341,7 +2536,6 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask)
if (mFolderAdded)
{
LLViewerInventoryCategory* category = gInventory.getCategory(mCatID);
-
if (NULL == category)
{
llwarns << "gInventory.getCategory(" << mCatID
@@ -2451,8 +2645,19 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
if (!cat) return;
const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
- copy_folder_to_outbox(cat, outbox_id, cat->getUUID());
+ copy_folder_to_outbox(cat, outbox_id, cat->getUUID(), LLToolDragAndDrop::getOperationId());
}
+#if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
+ else if (isMarketplaceSendAction(action))
+ {
+ llinfos << "Send to marketplace action!" << llendl;
+
+ LLInventoryCategory * cat = gInventory.getCategory(mUUID);
+ if (!cat) return;
+
+ send_to_marketplace(cat);
+ }
+#endif // ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
}
void LLFolderBridge::openItem()
@@ -2719,103 +2924,10 @@ void LLFolderBridge::pasteLinkFromClipboard()
void LLFolderBridge::staticFolderOptionsMenu()
{
LLFolderBridge* selfp = sSelf.get();
- if (selfp)
- {
- selfp->folderOptionsMenu();
- }
-}
-
-void LLFolderBridge::folderOptionsMenu()
-{
- LLInventoryModel* model = getInventoryModel();
- if(!model) return;
-
- const LLInventoryCategory* category = model->getCategory(mUUID);
- if(!category) return;
-
- const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if (trash_id == mUUID) return;
- if (isItemInTrash()) return;
- if (!isAgentInventory()) return;
- if (isOutboxFolder()) return;
-
- LLFolderType::EType type = category->getPreferredType();
- const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
- // BAP change once we're no longer treating regular categories as ensembles.
- const bool is_ensemble = (type == LLFolderType::FT_NONE ||
- LLFolderType::lookupIsEnsembleType(type));
-
- // Only enable calling-card related options for non-system folders.
- if (!is_system_folder)
- {
- LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
- if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
- {
- mItems.push_back(std::string("Calling Card Separator"));
- mItems.push_back(std::string("Conference Chat Folder"));
- mItems.push_back(std::string("IM All Contacts In Folder"));
- }
- }
-
- if (!isItemRemovable())
- {
- mDisabledItems.push_back(std::string("Delete"));
- }
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- if (LLFolderType::lookupIsProtectedType(type))
- {
- mItems.push_back(std::string("Delete System Folder"));
- }
-#endif
-
- // wearables related functionality for folders.
- //is_wearable
- LLFindWearables is_wearable;
- LLIsType is_object( LLAssetType::AT_OBJECT );
- LLIsType is_gesture( LLAssetType::AT_GESTURE );
-
- if (mWearables ||
- checkFolderForContentsOfType(model, is_wearable) ||
- checkFolderForContentsOfType(model, is_object) ||
- checkFolderForContentsOfType(model, is_gesture) )
- {
- mItems.push_back(std::string("Folder Wearables Separator"));
- // Only enable add/replace outfit for non-system folders.
- if (!is_system_folder)
- {
- // Adding an outfit onto another (versus replacing) doesn't make sense.
- if (type != LLFolderType::FT_OUTFIT)
- {
- mItems.push_back(std::string("Add To Outfit"));
- }
-
- mItems.push_back(std::string("Replace Outfit"));
- }
- if (is_ensemble)
- {
- mItems.push_back(std::string("Wear As Ensemble"));
- }
- mItems.push_back(std::string("Remove From Outfit"));
- if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
- {
- mDisabledItems.push_back(std::string("Remove From Outfit"));
- }
- if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
- {
- mDisabledItems.push_back(std::string("Replace Outfit"));
- }
- mItems.push_back(std::string("Outfit Separator"));
- }
- LLMenuGL* menup = dynamic_cast<LLMenuGL*>(mMenu.get());
- if (menup)
+ if (selfp && selfp->mRoot)
{
- hide_context_entries(*menup, mItems, mDisabledItems, TRUE);
-
- // Reposition the menu, in case we're adding items to an existing menu.
- menup->needsArrange();
- menup->arrangeAndClear();
+ selfp->mRoot->updateMenu();
}
}
@@ -2831,17 +2943,11 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv
return ((item_array.count() > 0) ? TRUE : FALSE );
}
-// Flags unused
-void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
{
- mItems.clear();
- mDisabledItems.clear();
-
- lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
-
-// menuentry_vec_t disabled_items;
LLInventoryModel* model = getInventoryModel();
- if(!model) return;
+ llassert(model != NULL);
+
const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
const LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
@@ -2858,10 +2964,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
mDisabledItems.push_back(std::string("New Body Parts"));
}
- // clear out old menu and folder pointers
- mMenu.markDead();
- sSelf.markDead();
-
if(trash_id == mUUID)
{
// This is the trash.
@@ -2875,20 +2977,23 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else if(isOutboxFolder())
{
- mItems.push_back(std::string("Delete"));
+ addOutboxContextMenuOptions(flags, mItems, mDisabledItems);
}
else if(isAgentInventory()) // do not allow creating in library
{
- LLViewerInventoryCategory *cat = getCategory();
+ LLViewerInventoryCategory *cat = getCategory();
// BAP removed protected check to re-enable standard ops in untyped folders.
// Not sure what the right thing is to do here.
if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT))
{
- if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox
+ if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox or outbox
{
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
+ {
mItems.push_back(std::string("New Folder"));
+ }
+
mItems.push_back(std::string("New Script"));
mItems.push_back(std::string("New Note"));
mItems.push_back(std::string("New Gesture"));
@@ -2959,34 +3064,138 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
mDisabledItems.push_back(std::string("Share"));
}
}
+}
- hide_context_entries(menu, mItems, mDisabledItems);
+void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
+{
+ // Build folder specific options back up
+ LLInventoryModel* model = getInventoryModel();
+ if(!model) return;
- // Add menu items that are dependent on the contents of the folder.
- uuid_vec_t folders;
- LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
- if (category)
+ const LLInventoryCategory* category = model->getCategory(mUUID);
+ if(!category) return;
+
+ const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (trash_id == mUUID) return;
+ if (isItemInTrash()) return;
+ if (!isAgentInventory()) return;
+ if (isOutboxFolder()) return;
+
+ LLFolderType::EType type = category->getPreferredType();
+ const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
+ // BAP change once we're no longer treating regular categories as ensembles.
+ const bool is_ensemble = (type == LLFolderType::FT_NONE ||
+ LLFolderType::lookupIsEnsembleType(type));
+
+ // Only enable calling-card related options for non-system folders.
+ if (!is_system_folder)
{
- folders.push_back(category->getUUID());
+ LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
+ if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
+ {
+ mItems.push_back(std::string("Calling Card Separator"));
+ mItems.push_back(std::string("Conference Chat Folder"));
+ mItems.push_back(std::string("IM All Contacts In Folder"));
+ }
}
- mMenu = menu.getHandle();
- sSelf = getHandle();
- LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE);
- fetch->startFetch();
- inc_busy_count();
- if(fetch->isFinished())
+ if (!isItemRemovable())
{
- // everything is already here - call done.
- fetch->done();
+ mDisabledItems.push_back(std::string("Delete"));
}
- else
+
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ if (LLFolderType::lookupIsProtectedType(type))
+ {
+ mItems.push_back(std::string("Delete System Folder"));
+ }
+#endif
+
+ // wearables related functionality for folders.
+ //is_wearable
+ LLFindWearables is_wearable;
+ LLIsType is_object( LLAssetType::AT_OBJECT );
+ LLIsType is_gesture( LLAssetType::AT_GESTURE );
+
+ if (mWearables ||
+ checkFolderForContentsOfType(model, is_wearable) ||
+ checkFolderForContentsOfType(model, is_object) ||
+ checkFolderForContentsOfType(model, is_gesture) )
{
- // it's all on its way - add an observer, and the inventory will call done for us when everything is here.
- gInventory.addObserver(fetch);
+ mItems.push_back(std::string("Folder Wearables Separator"));
+
+ // Only enable add/replace outfit for non-system folders.
+ if (!is_system_folder)
+ {
+ // Adding an outfit onto another (versus replacing) doesn't make sense.
+ if (type != LLFolderType::FT_OUTFIT)
+ {
+ mItems.push_back(std::string("Add To Outfit"));
+ }
+
+ mItems.push_back(std::string("Replace Outfit"));
+ }
+ if (is_ensemble)
+ {
+ mItems.push_back(std::string("Wear As Ensemble"));
+ }
+ mItems.push_back(std::string("Remove From Outfit"));
+ if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
+ {
+ mDisabledItems.push_back(std::string("Remove From Outfit"));
+ }
+ if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
+ {
+ mDisabledItems.push_back(std::string("Replace Outfit"));
+ }
+ mItems.push_back(std::string("Outfit Separator"));
}
}
+// Flags unused
+void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ sSelf.markDead();
+
+ mItems.clear();
+ mDisabledItems.clear();
+
+ lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
+
+ LLInventoryModel* model = getInventoryModel();
+ if(!model) return;
+
+ buildContextMenuBaseOptions(flags);
+
+ // Add menu items that are dependent on the contents of the folder.
+ LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
+ if (category)
+ {
+ uuid_vec_t folders;
+ folders.push_back(category->getUUID());
+
+ sSelf = getHandle();
+ LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE);
+ fetch->startFetch();
+ inc_busy_count();
+ if (fetch->isFinished())
+ {
+ buildContextMenuFolderOptions(flags);
+ }
+ else
+ {
+ // it's all on its way - add an observer, and the inventory will call done for us when everything is here.
+ gInventory.addObserver(fetch);
+ }
+ }
+
+ hide_context_entries(menu, mItems, mDisabledItems);
+
+ // Reposition the menu, in case we're adding items to an existing menu.
+ menu.needsArrange();
+ menu.arrangeAndClear();
+}
+
BOOL LLFolderBridge::hasChildren() const
{
LLInventoryModel* model = getInventoryModel();
@@ -3188,13 +3397,13 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
if(option == 0 && object)
{
- if (cat_and_wear && cat_and_wear->mWear)
+ if (cat_and_wear && cat_and_wear->mWear) // && !cat_and_wear->mFolderResponded)
{
LLInventoryObject::object_list_t inventory_objects;
object->getInventoryContents(inventory_objects);
int contents_count = inventory_objects.size()-1; //subtract one for containing folder
-
- LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count);
+ LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count, cat_and_wear->mFolderResponded);
+
gInventory.addObserver(inventoryObserver);
}
@@ -3307,8 +3516,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
LLInventoryModel* model = getInventoryModel();
- if(!model || !inv_item) return FALSE;
- if(!isAgentInventory()) return FALSE; // cannot drag into library
+ if (!model || !inv_item) return FALSE;
+ if (!isAgentInventory()) return FALSE; // cannot drag into library
if (!isAgentAvatarValid()) return FALSE;
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
@@ -3376,10 +3585,14 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
accept = TRUE;
if (!is_movable)
+ {
accept = FALSE;
- if ((mUUID == inv_item->getParentUUID()) && !move_is_into_favorites)
+ }
+ else if ((mUUID == inv_item->getParentUUID()) && !move_is_into_favorites)
+ {
accept = FALSE;
- if (move_is_into_current_outfit || move_is_into_outfit)
+ }
+ else if (move_is_into_current_outfit || move_is_into_outfit)
{
accept = can_move_to_outfit(inv_item, move_is_into_current_outfit);
}
@@ -3390,9 +3603,32 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
else if (move_is_into_outbox)
{
accept = can_move_to_outbox(inv_item, tooltip_msg);
+
+ if (accept)
+ {
+ const LLViewerInventoryCategory * master_folder = model->getFirstDescendantOf(outbox_id, mUUID);
+
+ int existing_item_count = LLToolDragAndDrop::instance().getCargoIDsCount();
+
+ if (master_folder != NULL)
+ {
+ LLInventoryModel::cat_array_t existing_categories;
+ LLInventoryModel::item_array_t existing_items;
+
+ gInventory.collectDescendents(master_folder->getUUID(), existing_categories, existing_items, FALSE);
+
+ existing_item_count += existing_items.count();
+ }
+
+ if (existing_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount"))
+ {
+ tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects");
+ accept = FALSE;
+ }
+ }
}
- if(accept && drop)
+ if (accept && drop)
{
if (inv_item->getType() == LLAssetType::AT_GESTURE
&& LLGestureMgr::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash)
@@ -3441,9 +3677,16 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
dropToOutfit(inv_item, move_is_into_current_outfit);
}
- else if (move_is_into_outbox && !move_is_from_outbox)
+ else if (move_is_into_outbox)
{
- copy_item_to_outbox(inv_item, outbox_id, LLUUID::null);
+ if (move_is_from_outbox)
+ {
+ move_item_within_outbox(inv_item, mUUID, LLToolDragAndDrop::getOperationId());
+ }
+ else
+ {
+ copy_item_to_outbox(inv_item, mUUID, LLUUID::null, LLToolDragAndDrop::getOperationId());
+ }
}
// NORMAL or TRASH folder
// (move the item, restamp if into trash)
@@ -3464,7 +3707,6 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
//
//--------------------------------------------------------------------------------
-
}
}
else if (LLToolDragAndDrop::SOURCE_WORLD == source)
@@ -3473,7 +3715,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// anonymous objects, it would be possible to bypass
// permissions.
object = gObjectList.findObject(inv_item->getParentUUID());
- if(!object)
+ if (!object)
{
llinfos << "Object not found for drop." << llendl;
return FALSE;
@@ -3483,10 +3725,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// move/copy this item.
LLPermissions perm(inv_item->getPermissions());
BOOL is_move = FALSE;
- if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID())
+ if ((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID())
&& perm.allowTransferTo(gAgent.getID())))
// || gAgent.isGodlike())
-
{
accept = TRUE;
}
@@ -3502,7 +3743,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// Don't allow placing an original item into Current Outfit or an outfit folder
// because they must contain only links to wearable items.
// *TODO: Probably we should create a link to an item if it was dragged to outfit or COF.
- if(move_is_into_current_outfit || move_is_into_outfit)
+ if (move_is_into_current_outfit || move_is_into_outfit)
{
accept = FALSE;
}
@@ -3513,8 +3754,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
accept = FALSE;
}
-
- if(drop && accept)
+ else if (move_is_into_outbox)
+ {
+ tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
+ accept = FALSE;
+ }
+
+ if (accept && drop)
{
LLMoveInv* move_inv = new LLMoveInv;
move_inv->mObjectID = inv_item->getParentUUID();
@@ -3536,15 +3782,22 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLNotifications::instance().forceResponse(params, 0);
}
}
-
}
else if(LLToolDragAndDrop::SOURCE_NOTECARD == source)
{
- // Don't allow placing an original item from a notecard to Current Outfit or an outfit folder
- // because they must contain only links to wearable items.
- accept = !(move_is_into_current_outfit || move_is_into_outfit);
-
- if(accept && drop)
+ if (move_is_into_outbox)
+ {
+ tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
+ accept = FALSE;
+ }
+ else
+ {
+ // Don't allow placing an original item from a notecard to Current Outfit or an outfit folder
+ // because they must contain only links to wearable items.
+ accept = !(move_is_into_current_outfit || move_is_into_outfit);
+ }
+
+ if (accept && drop)
{
copy_inventory_from_notecard(mUUID, // Drop to the chosen destination folder
LLToolDragAndDrop::getInstance()->getObjectID(),
@@ -3559,7 +3812,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
accept = TRUE;
- if (move_is_into_current_outfit || move_is_into_outfit)
+ if (move_is_into_outbox)
+ {
+ tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
+ accept = FALSE;
+ }
+ else if (move_is_into_current_outfit || move_is_into_outfit)
{
accept = can_move_to_outfit(inv_item, move_is_into_current_outfit);
}
@@ -3650,7 +3908,7 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else if(isOutboxFolder())
{
- items.push_back(std::string("Delete"));
+ addOutboxContextMenuOptions(flags, items, disabled_items);
}
else
{
@@ -3724,29 +3982,29 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
menuentry_vec_t items;
menuentry_vec_t disabled_items;
- if(isItemInTrash())
- {
- addTrashContextMenuOptions(items, disabled_items);
- }
- else if(isOutboxFolder())
+ if (isOutboxFolder())
{
- items.push_back(std::string("Delete"));
+ addOutboxContextMenuOptions(flags, items, disabled_items);
}
else
{
- items.push_back(std::string("Share"));
- if (!canShare())
+ if (isItemInTrash())
{
- disabled_items.push_back(std::string("Share"));
- }
- items.push_back(std::string("Sound Open"));
- items.push_back(std::string("Properties"));
+ addTrashContextMenuOptions(items, disabled_items);
+ }
+ else
+ {
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
+ items.push_back(std::string("Sound Open"));
+ items.push_back(std::string("Properties"));
- getClipboardEntries(true, items, disabled_items, flags);
- }
+ getClipboardEntries(true, items, disabled_items, flags);
+ }
- if (!isOutboxFolder())
- {
items.push_back(std::string("Sound Separator"));
items.push_back(std::string("Sound Play"));
}
@@ -3782,29 +4040,29 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
menuentry_vec_t disabled_items;
lldebugs << "LLLandmarkBridge::buildContextMenu()" << llendl;
- if(isItemInTrash())
- {
- addTrashContextMenuOptions(items, disabled_items);
- }
- else if(isOutboxFolder())
+ if(isOutboxFolder())
{
- items.push_back(std::string("Delete"));
+ addOutboxContextMenuOptions(flags, items, disabled_items);
}
else
{
- items.push_back(std::string("Share"));
- if (!canShare())
+ if(isItemInTrash())
{
- disabled_items.push_back(std::string("Share"));
- }
- items.push_back(std::string("Landmark Open"));
- items.push_back(std::string("Properties"));
+ addTrashContextMenuOptions(items, disabled_items);
+ }
+ else
+ {
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
+ items.push_back(std::string("Landmark Open"));
+ items.push_back(std::string("Properties"));
- getClipboardEntries(true, items, disabled_items, flags);
- }
+ getClipboardEntries(true, items, disabled_items, flags);
+ }
- if (!isOutboxFolder())
- {
items.push_back(std::string("Landmark Separator"));
items.push_back(std::string("About Landmark"));
}
@@ -4337,36 +4595,35 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
menuentry_vec_t disabled_items;
lldebugs << "LLAnimationBridge::buildContextMenu()" << llendl;
- if(isItemInTrash())
- {
- addTrashContextMenuOptions(items, disabled_items);
- }
- else if(isOutboxFolder())
+ if(isOutboxFolder())
{
items.push_back(std::string("Delete"));
}
else
{
- items.push_back(std::string("Share"));
- if (!canShare())
+ if(isItemInTrash())
{
- disabled_items.push_back(std::string("Share"));
- }
- items.push_back(std::string("Animation Open"));
- items.push_back(std::string("Properties"));
+ addTrashContextMenuOptions(items, disabled_items);
+ }
+ else
+ {
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
+ items.push_back(std::string("Animation Open"));
+ items.push_back(std::string("Properties"));
- getClipboardEntries(true, items, disabled_items, flags);
- }
+ getClipboardEntries(true, items, disabled_items, flags);
+ }
- if (!isOutboxFolder())
- {
items.push_back(std::string("Animation Separator"));
items.push_back(std::string("Animation Play"));
items.push_back(std::string("Animation Audition"));
}
hide_context_entries(menu, items, disabled_items);
-
}
// virtual
@@ -5351,7 +5608,7 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else if(isOutboxFolder())
{
- items.push_back(std::string("Delete"));
+ addOutboxContextMenuOptions(flags, items, disabled_items);
}
else
{
@@ -5360,7 +5617,6 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
getClipboardEntries(true, items, disabled_items, flags);
}
-
hide_context_entries(menu, items, disabled_items);
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 2d625befb4..871657a58a 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -69,9 +69,9 @@ public:
U32 flags = 0x00);
virtual ~LLInvFVBridge() {}
- BOOL canShare() const;
- BOOL canListOnMarketplace() const;
- BOOL canListOnMarketplaceNow() const;
+ bool canShare() const;
+ bool canListOnMarketplace() const;
+ bool canListOnMarketplaceNow() const;
//--------------------------------------------------------------------
// LLInvFVBridge functionality
@@ -131,6 +131,9 @@ protected:
virtual void addDeleteContextMenuOptions(menuentry_vec_t &items,
menuentry_vec_t &disabled_items);
virtual void addOpenRightClickMenuOption(menuentry_vec_t &items);
+ virtual void addOutboxContextMenuOptions(U32 flags,
+ menuentry_vec_t &items,
+ menuentry_vec_t &disabled_items);
protected:
LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
@@ -144,6 +147,7 @@ protected:
BOOL isCOFFolder() const; // true if COF or descendent of
BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox
BOOL isOutboxFolder() const; // true if COF or descendent of marketplace outbox
+ BOOL isOutboxFolderDirectParent() const;
const LLUUID getOutboxFolder() const;
virtual BOOL isItemPermissive() const;
@@ -278,6 +282,9 @@ public:
LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
protected:
+ void buildContextMenuBaseOptions(U32 flags);
+ void buildContextMenuFolderOptions(U32 flags);
+
//--------------------------------------------------------------------
// Menu callbacks
//--------------------------------------------------------------------
@@ -306,8 +313,6 @@ protected:
void dropToFavorites(LLInventoryItem* inv_item);
void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
- void dropToOutbox(LLInventoryItem* inv_item);
- void dropFolderToOutbox(LLInventoryCategory* inv_cat);
//--------------------------------------------------------------------
// Messy hacks for handling folder options
@@ -315,12 +320,10 @@ protected:
public:
static LLHandle<LLFolderBridge> sSelf;
static void staticFolderOptionsMenu();
- void folderOptionsMenu();
private:
BOOL mCallingCards;
BOOL mWearables;
- LLHandle<LLView> mMenu;
menuentry_vec_t mItems;
menuentry_vec_t mDisabledItems;
LLRootHandle<LLFolderBridge> mHandle;
@@ -650,7 +653,6 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
// are set as enabled.
void hide_context_entries(LLMenuGL& menu,
const menuentry_vec_t &entries_to_show,
- const menuentry_vec_t &disabled_entries,
- BOOL append = FALSE);
+ const menuentry_vec_t &disabled_entries);
#endif // LL_LLINVENTORYBRIDGE_H
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 5fb3f15cd5..dd92188e9d 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -58,6 +58,7 @@
#include "llinventorymodel.h"
#include "llinventorypanel.h"
#include "lllineeditor.h"
+#include "llmarketplacenotifications.h"
#include "llmenugl.h"
#include "llnotificationsutil.h"
#include "llpanelmaininventory.h"
@@ -82,6 +83,8 @@
#include "llvoavatarself.h"
#include "llwearablelist.h"
+#include <boost/foreach.hpp>
+
BOOL LLInventoryState::sWearNewClothing = FALSE;
LLUUID LLInventoryState::sWearNewClothingTransactionID;
@@ -530,21 +533,37 @@ void show_item_original(const LLUUID& item_uuid)
}
}
-void move_to_outbox_cb(const LLSD& notification, const LLSD& response)
+
+void open_outbox()
+{
+ LLFloaterReg::showInstance("outbox");
+}
+
+LLUUID create_folder_in_outbox_for_item(LLInventoryItem* item, const LLUUID& destFolderId, S32 operation_id)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0) return; // canceled
+ llassert(item);
+ llassert(destFolderId.notNull());
+
+ LLUUID created_folder_id = gInventory.createNewCategory(destFolderId, LLFolderType::FT_NONE, item->getName());
+ gInventory.notifyObservers();
+
+ LLNotificationsUtil::add("OutboxFolderCreated");
+
+ return created_folder_id;
+}
- LLViewerInventoryItem * viitem = gInventory.getItem(notification["payload"]["item_id"].asUUID());
- LLUUID dest_folder_id = notification["payload"]["dest_folder_id"].asUUID();
+void move_to_outbox_cb_action(const LLSD& payload)
+{
+ LLViewerInventoryItem * viitem = gInventory.getItem(payload["item_id"].asUUID());
+ LLUUID dest_folder_id = payload["dest_folder_id"].asUUID();
if (viitem)
{
// when moving item directly into outbox create folder with that name
if (dest_folder_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
{
- dest_folder_id = gInventory.createNewCategory(dest_folder_id, LLFolderType::FT_NONE, viitem->getName());
- gInventory.notifyObservers();
+ S32 operation_id = payload["operation_id"].asInteger();
+ dest_folder_id = create_folder_in_outbox_for_item(viitem, dest_folder_id, operation_id);
}
LLUUID parent = viitem->getParentUUID();
@@ -555,12 +574,12 @@ void move_to_outbox_cb(const LLSD& notification, const LLSD& response)
dest_folder_id,
false);
- LLUUID top_level_folder = notification["payload"]["top_level_folder"].asUUID();
+ LLUUID top_level_folder = payload["top_level_folder"].asUUID();
if (top_level_folder != LLUUID::null)
{
LLViewerInventoryCategory* category;
-
+
while (parent.notNull())
{
LLInventoryModel::cat_array_t* cat_array;
@@ -589,42 +608,75 @@ void move_to_outbox_cb(const LLSD& notification, const LLSD& response)
}
}
+ open_outbox();
}
}
-
-void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder)
+void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder, S32 operation_id)
{
- if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
+ // Collapse links directly to items/folders
+ LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item;
+ LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory();
+ if (linked_category != NULL)
{
- // when moving item directly into outbox create folder with that name
- if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
+ copy_folder_to_outbox(linked_category, dest_folder, top_level_folder, operation_id);
+ }
+ else
+ {
+ LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem();
+ if (linked_item != NULL)
{
- dest_folder = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, inv_item->getName());
- gInventory.notifyObservers();
+ inv_item = (LLInventoryItem *) linked_item;
+ }
+
+ // Check for copy permissions
+ if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
+ {
+ // when moving item directly into outbox create folder with that name
+ if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
+ {
+ dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, operation_id);
+ }
+
+ copy_inventory_item(gAgent.getID(),
+ inv_item->getPermissions().getOwner(),
+ inv_item->getUUID(),
+ dest_folder,
+ inv_item->getName(),
+ LLPointer<LLInventoryCallback>(NULL));
+
+ open_outbox();
+ }
+ else
+ {
+ LLSD payload;
+ payload["item_id"] = inv_item->getUUID();
+ payload["dest_folder_id"] = dest_folder;
+ payload["top_level_folder"] = top_level_folder;
+ payload["operation_id"] = operation_id;
+
+ LLMarketplaceInventoryNotifications::addNoCopyNotification(payload, move_to_outbox_cb_action);
}
-
- copy_inventory_item(
- gAgent.getID(),
- inv_item->getPermissions().getOwner(),
- inv_item->getUUID(),
- dest_folder,
- inv_item->getName(),
- LLPointer<LLInventoryCallback>(NULL));
}
- else
- {
- LLSD args;
- args["ITEM_NAME"] = inv_item->getName();
- LLSD payload;
- payload["item_id"] = inv_item->getUUID();
- payload["dest_folder_id"] = dest_folder;
- payload["top_level_folder"] = top_level_folder;
- LLNotificationsUtil::add("ConfirmNoCopyToOutbox", args, payload, boost::bind(&move_to_outbox_cb, _1, _2));
+}
+
+void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id)
+{
+ // when moving item directly into outbox create folder with that name
+ if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
+ {
+ dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, operation_id);
}
+
+ LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item;
+
+ change_item_parent(&gInventory,
+ viewer_inv_item,
+ dest_folder,
+ false);
}
-void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder)
+void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id)
{
LLUUID new_folder_id = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, inv_cat->getName());
gInventory.notifyObservers();
@@ -639,7 +691,7 @@ void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_fold
for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
{
LLInventoryItem* item = *iter;
- copy_item_to_outbox(item, new_folder_id, top_level_folder);
+ copy_item_to_outbox(item, new_folder_id, top_level_folder, operation_id);
}
LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
@@ -647,14 +699,10 @@ void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_fold
for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
{
LLViewerInventoryCategory* category = *iter;
- copy_folder_to_outbox(category, new_folder_id, top_level_folder);
+ copy_folder_to_outbox(category, new_folder_id, top_level_folder, operation_id);
}
- // delete the folder if we have emptied it
- //if (cat_array->empty() && item_array->empty())
- //{
- // remove_category(inventory_model, inv_cat->getUUID());
- //}
+ open_outbox();
}
///----------------------------------------------------------------------------
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 7b452537f8..ce2b89b22e 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -74,9 +74,10 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s
// Generates a string containing the path to the item specified by item_id.
void append_path(const LLUUID& id, std::string& path);
-void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder);
+void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder, S32 operation_id);
+void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id);
-void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder);
+void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id);
/** Miscellaneous global functions
** **
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index dc25689fa3..a71b699fdd 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -217,6 +217,38 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons
return NULL;
}
+//
+// Search up the parent chain until we get to the specified parent, then return the first child category under it
+//
+const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LLUUID& master_parent_id, const LLUUID& obj_id) const
+{
+ if (master_parent_id == obj_id)
+ {
+ return NULL;
+ }
+
+ const LLViewerInventoryCategory* current_cat = getCategory(obj_id);
+
+ if (current_cat == NULL)
+ {
+ current_cat = getCategory(getObject(obj_id)->getParentUUID());
+ }
+
+ while (current_cat != NULL)
+ {
+ const LLUUID& current_parent_id = current_cat->getParentUUID();
+
+ if (current_parent_id == master_parent_id)
+ {
+ return current_cat;
+ }
+
+ current_cat = getCategory(current_parent_id);
+ }
+
+ return NULL;
+}
+
// Get the object by id. Returns NULL if not found.
LLInventoryObject* LLInventoryModel::getObject(const LLUUID& id) const
{
@@ -377,14 +409,67 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
return rv;
}
+class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
+{
+public:
+ LLCreateInventoryCategoryResponder(LLInventoryModel* model,
+ void (*callback)(const LLSD&, void*),
+ void* user_data) :
+ mModel(model),
+ mCallback(callback),
+ mData(user_data)
+ {
+ }
+
+ virtual void error(U32 status, const std::string& reason)
+ {
+ LL_WARNS("InvAPI") << "CreateInventoryCategory failed. status = " << status << ", reasion = \"" << reason << "\"" << LL_ENDL;
+ }
+
+ virtual void result(const LLSD& content)
+ {
+ //Server has created folder.
+
+ LLUUID category_id = content["folder_id"].asUUID();
+
+
+ // Add the category to the internal representation
+ LLPointer<LLViewerInventoryCategory> cat =
+ new LLViewerInventoryCategory( category_id,
+ content["parent_id"].asUUID(),
+ (LLFolderType::EType)content["type"].asInteger(),
+ content["name"].asString(),
+ gAgent.getID() );
+ cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
+ cat->setDescendentCount(0);
+ LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+ mModel->accountForUpdate(update);
+ mModel->updateCategory(cat);
+
+ if (mCallback && mData)
+ {
+ mCallback(content, mData);
+ }
+
+ }
+
+private:
+ void (*mCallback)(const LLSD&, void*);
+ void* mData;
+ LLInventoryModel* mModel;
+};
+
// Convenience function to create a new category. You could call
// updateCategory() with a newly generated UUID category, but this
// version will take care of details like what the name should be
// based on preferred type. Returns the UUID of the new category.
LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
LLFolderType::EType preferred_type,
- const std::string& pname)
+ const std::string& pname,
+ void (*callback)(const LLSD&, void*), //Default to NULL
+ void* user_data) //Default to NULL
{
+
LLUUID id;
if(!isInventoryUsable())
{
@@ -408,6 +493,35 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
{
name.assign(LLViewerFolderType::lookupNewCategoryName(preferred_type));
}
+
+ if ( callback && user_data ) //callback required for acked message.
+ {
+ LLViewerRegion* viewer_region = gAgent.getRegion();
+ std::string url;
+ if ( viewer_region )
+ url = viewer_region->getCapability("CreateInventoryCategory");
+
+ if (!url.empty())
+ {
+ //Let's use the new capability.
+
+ LLSD request, body;
+ body["folder_id"] = id;
+ body["parent_id"] = parent_id;
+ body["type"] = (LLSD::Integer) preferred_type;
+ body["name"] = name;
+
+ request["message"] = "CreateInventoryCategory";
+ request["payload"] = body;
+
+ // viewer_region->getCapAPI().post(request);
+ LLHTTPClient::post(
+ url,
+ body,
+ new LLCreateInventoryCategoryResponder(this, callback, user_data) );
+ return LLUUID::null;
+ }
+ }
// Add the category to the internal representation
LLPointer<LLViewerInventoryCategory> cat =
@@ -1087,7 +1201,6 @@ void LLInventoryModel::notifyObservers()
iter != mObservers.end(); )
{
LLInventoryObserver* observer = *iter;
-
observer->changed(mModifyMask);
// safe way to increment since changed may delete entries! (@!##%@!@&*!)
@@ -2574,7 +2687,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
<< titem->getParentUUID() << llendl;
U32 callback_id;
msg->getU32Fast(_PREHASH_ItemData, _PREHASH_CallbackID, callback_id);
- if(titem->getUUID().notNull())
+ if(titem->getUUID().notNull() ) // && callback_id.notNull() )
{
items.push_back(titem);
cblist.push_back(InventoryCallbackInfo(callback_id, titem->getUUID()));
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 340c1b0c22..7cd85c4ab7 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -64,6 +64,7 @@ class LLInventoryCollectFunctor;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLInventoryModel
{
+ LOG_CLASS(LLInventoryModel);
public:
friend class LLInventoryModelFetchDescendentsResponder;
@@ -238,6 +239,9 @@ public:
// Get whatever special folder this object is a child of, if any.
const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const;
+
+ // Get first descendant of the child object under the specified parent
+ const LLViewerInventoryCategory *getFirstDescendantOf(const LLUUID& master_parent_id, const LLUUID& obj_id) const;
// Get the object by id. Returns NULL if not found.
// NOTE: Use the pointer returned for read operations - do
@@ -360,7 +364,9 @@ public:
// name based on type, pass in a NULL to the 'name' parameter.
LLUUID createNewCategory(const LLUUID& parent_id,
LLFolderType::EType preferred_type,
- const std::string& name);
+ const std::string& name,
+ void (*callback)(const LLSD&, void*) = NULL,
+ void* user_data = NULL );
protected:
// Internal methods that add inventory and make sure that all of
// the internal data structures are consistent. These methods
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index d06374d232..382569fa3a 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -132,6 +132,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mAcceptsDragAndDrop(p.accepts_drag_and_drop),
mAllowMultiSelect(p.allow_multi_select),
mShowItemLinkOverlays(p.show_item_link_overlays),
+ mShowEmptyMessage(p.show_empty_message),
mShowLoadStatus(p.show_load_status),
mViewsInitialized(false),
mInvFVBridgeBuilder(NULL)
@@ -617,6 +618,7 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u
p.listener = bridge;
p.use_label_suffix = useLabelSuffix;
p.allow_multiselect = mAllowMultiSelect;
+ p.show_empty_message = mShowEmptyMessage;
p.show_load_status = mShowLoadStatus;
return LLUICtrlFactory::create<LLFolderView>(p);
@@ -1105,30 +1107,23 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
return FALSE;
}
- LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
-
- // A. If the inventory side panel floater is open, use that preferably.
- if (is_inventorysp_active())
- {
- // Get the floater's z order to compare it to other inventory floaters' order later.
- res = sidepanel_inventory->getActivePanel();
- z_min = gFloaterView->getZOrder(floater_inventory);
- active_inv_floaterp = floater_inventory;
- }
+ LLSidepanelInventory *inventory_panel = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
- // B. Iterate through the inventory floaters and return whichever is on top.
+ // Iterate through the inventory floaters and return whichever is on top.
LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
{
- LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter);
- if (iv && iv->getVisible())
+ LLFloaterSidePanelContainer* inventory_floater = dynamic_cast<LLFloaterSidePanelContainer*>(*iter);
+ inventory_panel = inventory_floater->findChild<LLSidepanelInventory>("main_panel");
+
+ if (inventory_floater && inventory_panel && inventory_floater->getVisible())
{
- S32 z_order = gFloaterView->getZOrder(iv);
+ S32 z_order = gFloaterView->getZOrder(inventory_floater);
if (z_order < z_min)
{
- res = iv->getPanel();
+ res = inventory_panel->getActivePanel();
z_min = z_order;
- active_inv_floaterp = iv;
+ active_inv_floaterp = inventory_floater;
}
}
}
@@ -1145,7 +1140,7 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
{
floater_inventory->openFloater();
- res = sidepanel_inventory->getActivePanel();
+ res = inventory_panel->getActivePanel();
}
return res;
@@ -1164,7 +1159,6 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
LLViewerInventoryCategory * cat = gInventory.getCategory(obj_id);
bool in_inbox = false;
- bool in_outbox = false;
LLViewerInventoryCategory * parent_cat = NULL;
@@ -1180,10 +1174,9 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
if (parent_cat)
{
in_inbox = (LLFolderType::FT_INBOX == parent_cat->getPreferredType());
- in_outbox = (LLFolderType::FT_OUTBOX == parent_cat->getPreferredType());
}
- if (in_inbox || in_outbox)
+ if (in_inbox)
{
LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
LLInventoryPanel * inventory_panel = NULL;
@@ -1193,11 +1186,6 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
sidepanel_inventory->openInbox();
inventory_panel = sidepanel_inventory->getInboxPanel();
}
- else
- {
- sidepanel_inventory->openOutbox();
- inventory_panel = sidepanel_inventory->getOutboxPanel();
- }
if (inventory_panel)
{
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 2a24327115..8279163762 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -84,6 +84,7 @@ public:
Optional<Filter> filter;
Optional<std::string> start_folder;
Optional<bool> use_label_suffix;
+ Optional<bool> show_empty_message;
Optional<bool> show_load_status;
Optional<LLScrollContainer::Params> scroll;
Optional<bool> accepts_drag_and_drop;
@@ -96,6 +97,7 @@ public:
filter("filter"),
start_folder("start_folder"),
use_label_suffix("use_label_suffix", true),
+ show_empty_message("show_empty_message", true),
show_load_status("show_load_status"),
scroll("scroll"),
accepts_drag_and_drop("accepts_drag_and_drop")
@@ -188,6 +190,7 @@ protected:
BOOL mAcceptsDragAndDrop;
BOOL mAllowMultiSelect;
BOOL mShowItemLinkOverlays; // Shows link graphic over inventory item icons
+ BOOL mShowEmptyMessage;
BOOL mShowLoadStatus;
LLFolderView* mFolderRoot;
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
new file mode 100644
index 0000000000..a3f0a6062c
--- /dev/null
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -0,0 +1,463 @@
+/**
+ * @file llmarketplacefunctions.cpp
+ * @brief Implementation of assorted functions related to the marketplace
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llmarketplacefunctions.h"
+
+#include "llagent.h"
+#include "llhttpclient.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llviewermedia.h"
+#include "llviewernetwork.h"
+
+
+//
+// Helpers
+//
+
+static std::string getMarketplaceDomain()
+{
+ std::string domain = "secondlife.com";
+
+ if (!LLGridManager::getInstance()->isInProductionGrid())
+ {
+ const std::string& grid_label = LLGridManager::getInstance()->getGridLabel();
+ const std::string& grid_label_lower = utf8str_tolower(grid_label);
+
+ if (grid_label_lower == "damballah")
+ {
+ domain = "secondlife-staging.com";
+ }
+ else
+ {
+ domain = llformat("%s.lindenlab.com", grid_label_lower.c_str());
+ }
+ }
+
+ return domain;
+}
+
+static std::string getMarketplaceURL(const std::string& urlStringName)
+{
+ LLStringUtil::format_map_t domain_arg;
+ domain_arg["[MARKETPLACE_DOMAIN_NAME]"] = getMarketplaceDomain();
+
+ std::string marketplace_url = LLTrans::getString(urlStringName, domain_arg);
+
+ return marketplace_url;
+}
+
+LLSD getMarketplaceStringSubstitutions()
+{
+ std::string marketplace_url = getMarketplaceURL("MarketplaceURL");
+ std::string marketplace_url_create = getMarketplaceURL("MarketplaceURL_CreateStore");
+ std::string marketplace_url_dashboard = getMarketplaceURL("MarketplaceURL_Dashboard");
+ std::string marketplace_url_imports = getMarketplaceURL("MarketplaceURL_Imports");
+ std::string marketplace_url_info = getMarketplaceURL("MarketplaceURL_LearnMore");
+
+ LLSD marketplace_sub_map;
+
+ marketplace_sub_map["[MARKETPLACE_URL]"] = marketplace_url;
+ marketplace_sub_map["[MARKETPLACE_CREATE_STORE_URL]"] = marketplace_url_create;
+ marketplace_sub_map["[MARKETPLACE_LEARN_MORE_URL]"] = marketplace_url_info;
+ marketplace_sub_map["[MARKETPLACE_DASHBOARD_URL]"] = marketplace_url_dashboard;
+ marketplace_sub_map["[MARKETPLACE_IMPORTS_URL]"] = marketplace_url_imports;
+
+ return marketplace_sub_map;
+}
+
+namespace LLMarketplaceImport
+{
+ // Basic interface for this namespace
+
+ bool hasSessionCookie();
+ bool inProgress();
+ bool resultPending();
+ U32 getResultStatus();
+ const LLSD& getResults();
+
+ bool establishMarketplaceSessionCookie();
+ bool pollStatus();
+ bool triggerImport();
+
+ // Internal state variables
+
+ static std::string sMarketplaceCookie = "";
+ static LLSD sImportId = LLSD::emptyMap();
+ static bool sImportInProgress = false;
+ static bool sImportPostPending = false;
+ static bool sImportGetPending = false;
+ static U32 sImportResultStatus = 0;
+ static LLSD sImportResults = LLSD::emptyMap();
+
+ // Responders
+
+ class LLImportPostResponder : public LLHTTPClient::Responder
+ {
+ public:
+ LLImportPostResponder() : LLCurl::Responder() {}
+
+ void completed(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ llinfos << " SLM POST status: " << status << llendl;
+ llinfos << " SLM POST reason: " << reason << llendl;
+ llinfos << " SLM POST content: " << content.asString() << llendl;
+ }
+
+ if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) ||
+ (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
+ (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
+ {
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl;
+ }
+
+ sMarketplaceCookie.clear();
+ }
+
+ sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE);
+ sImportPostPending = false;
+ sImportResultStatus = status;
+ sImportId = content;
+ }
+ };
+
+ class LLImportGetResponder : public LLHTTPClient::Responder
+ {
+ public:
+ LLImportGetResponder() : LLCurl::Responder() {}
+
+ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+ {
+ const std::string& set_cookie_string = content["set-cookie"].asString();
+
+ if (!set_cookie_string.empty())
+ {
+ sMarketplaceCookie = set_cookie_string;
+ }
+ }
+
+ void completed(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ llinfos << " SLM GET status: " << status << llendl;
+ llinfos << " SLM GET reason: " << reason << llendl;
+ llinfos << " SLM GET content: " << content.asString() << llendl;
+ }
+
+ if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
+ (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
+ {
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl;
+ }
+
+ sMarketplaceCookie.clear();
+ }
+
+ sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
+ sImportGetPending = false;
+ sImportResultStatus = status;
+ sImportResults = content;
+ }
+ };
+
+ // Basic API
+
+ bool hasSessionCookie()
+ {
+ return !sMarketplaceCookie.empty();
+ }
+
+ bool inProgress()
+ {
+ return sImportInProgress;
+ }
+
+ bool resultPending()
+ {
+ return (sImportPostPending || sImportGetPending);
+ }
+
+ U32 getResultStatus()
+ {
+ return sImportResultStatus;
+ }
+
+ const LLSD& getResults()
+ {
+ return sImportResults;
+ }
+
+ static std::string getInventoryImportURL()
+ {
+ std::string url = getMarketplaceURL("MarketplaceURL");
+
+ url += "api/1/";
+ url += gAgent.getID().getString();
+ url += "/inventory/import/";
+
+ return url;
+ }
+
+ bool establishMarketplaceSessionCookie()
+ {
+ if (hasSessionCookie())
+ {
+ return false;
+ }
+
+ sImportInProgress = true;
+ sImportGetPending = true;
+
+ std::string url = getInventoryImportURL();
+
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ llinfos << " SLM GET: " << url << llendl;
+ }
+
+ LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders());
+
+ return true;
+ }
+
+ bool pollStatus()
+ {
+ if (!hasSessionCookie())
+ {
+ return false;
+ }
+
+ sImportGetPending = true;
+
+ std::string url = getInventoryImportURL();
+
+ url += sImportId.asString();
+
+ // Make the headers for the post
+ LLSD headers = LLSD::emptyMap();
+ headers["Accept"] = "*/*";
+ headers["Cookie"] = sMarketplaceCookie;
+ headers["Content-Type"] = "application/llsd+xml";
+ headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent();
+
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ llinfos << " SLM GET: " << url << llendl;
+ }
+
+ LLHTTPClient::get(url, new LLImportGetResponder(), headers);
+
+ return true;
+ }
+
+ bool triggerImport()
+ {
+ if (!hasSessionCookie())
+ {
+ return false;
+ }
+
+ sImportId = LLSD::emptyMap();
+ sImportInProgress = true;
+ sImportPostPending = true;
+ sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING;
+ sImportResults = LLSD::emptyMap();
+
+ std::string url = getInventoryImportURL();
+
+ // Make the headers for the post
+ LLSD headers = LLSD::emptyMap();
+ headers["Accept"] = "*/*";
+ headers["Connection"] = "Keep-Alive";
+ headers["Cookie"] = sMarketplaceCookie;
+ headers["Content-Type"] = "application/xml";
+ headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent();
+
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ llinfos << " SLM POST: " << url << llendl;
+ }
+
+ LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);
+
+ return true;
+ }
+}
+
+
+//
+// Interface class
+//
+
+
+//static
+void LLMarketplaceInventoryImporter::update()
+{
+ if (instanceExists())
+ {
+ LLMarketplaceInventoryImporter::instance().updateImport();
+ }
+}
+
+LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()
+ : mAutoTriggerImport(false)
+ , mImportInProgress(false)
+ , mInitialized(false)
+ , mErrorInitSignal(NULL)
+ , mStatusChangedSignal(NULL)
+ , mStatusReportSignal(NULL)
+{
+}
+
+boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErrorCallback(const status_report_signal_t::slot_type& cb)
+{
+ if (mErrorInitSignal == NULL)
+ {
+ mErrorInitSignal = new status_report_signal_t();
+ }
+
+ return mErrorInitSignal->connect(cb);
+}
+
+boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb)
+{
+ if (mStatusChangedSignal == NULL)
+ {
+ mStatusChangedSignal = new status_changed_signal_t();
+ }
+
+ return mStatusChangedSignal->connect(cb);
+}
+
+boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallback(const status_report_signal_t::slot_type& cb)
+{
+ if (mStatusReportSignal == NULL)
+ {
+ mStatusReportSignal = new status_report_signal_t();
+ }
+
+ return mStatusReportSignal->connect(cb);
+}
+
+void LLMarketplaceInventoryImporter::initialize()
+{
+ llassert(!mInitialized);
+
+ if (!LLMarketplaceImport::hasSessionCookie())
+ {
+ LLMarketplaceImport::establishMarketplaceSessionCookie();
+ }
+}
+
+void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport()
+{
+ mInitialized = false;
+
+ initialize();
+
+ mAutoTriggerImport = true;
+}
+
+bool LLMarketplaceInventoryImporter::triggerImport()
+{
+ const bool import_triggered = LLMarketplaceImport::triggerImport();
+
+ if (!import_triggered)
+ {
+ reinitializeAndTriggerImport();
+ }
+
+ return import_triggered;
+}
+
+void LLMarketplaceInventoryImporter::updateImport()
+{
+ const bool in_progress = LLMarketplaceImport::inProgress();
+
+ if (in_progress && !LLMarketplaceImport::resultPending())
+ {
+ const bool polling_status = LLMarketplaceImport::pollStatus();
+
+ if (!polling_status)
+ {
+ reinitializeAndTriggerImport();
+ }
+ }
+
+ if (mImportInProgress != in_progress)
+ {
+ mImportInProgress = in_progress;
+
+ // If we are no longer in progress
+ if (!mImportInProgress)
+ {
+ if (mInitialized)
+ {
+ // Report results
+ if (mStatusReportSignal)
+ {
+ (*mStatusReportSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
+ }
+ }
+ else
+ {
+ // Look for results success
+ mInitialized = LLMarketplaceImport::hasSessionCookie();
+
+ if (mInitialized)
+ {
+ // Follow up with auto trigger of import
+ if (mAutoTriggerImport)
+ {
+ mAutoTriggerImport = false;
+
+ mImportInProgress = triggerImport();
+ }
+ }
+ else if (mErrorInitSignal)
+ {
+ (*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
+ }
+ }
+ }
+
+ // Make sure we trigger the status change with the final state (in case of auto trigger after initialize)
+ if (mStatusChangedSignal)
+ {
+ (*mStatusChangedSignal)(mImportInProgress);
+ }
+ }
+}
+
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
new file mode 100644
index 0000000000..4b8f7a1ac7
--- /dev/null
+++ b/indra/newview/llmarketplacefunctions.h
@@ -0,0 +1,94 @@
+/**
+ * @file llmarketplacefunctions.h
+ * @brief Miscellaneous marketplace-related functions and classes
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMARKETPLACEFUNCTIONS_H
+#define LL_LLMARKETPLACEFUNCTIONS_H
+
+
+#include <llsd.h>
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+#include "llsingleton.h"
+#include "llstring.h"
+
+
+LLSD getMarketplaceStringSubstitutions();
+
+
+namespace MarketplaceErrorCodes
+{
+ enum eCode
+ {
+ IMPORT_DONE = 200,
+ IMPORT_PROCESSING = 202,
+ IMPORT_REDIRECT = 302,
+ IMPORT_AUTHENTICATION_ERROR = 401,
+ IMPORT_DONE_WITH_ERRORS = 409,
+ IMPORT_JOB_FAILED = 410,
+ IMPORT_JOB_TIMEOUT = 499,
+ };
+}
+
+
+class LLMarketplaceInventoryImporter
+ : public LLSingleton<LLMarketplaceInventoryImporter>
+{
+public:
+ static void update();
+
+ LLMarketplaceInventoryImporter();
+
+ typedef boost::signals2::signal<void (bool)> status_changed_signal_t;
+ typedef boost::signals2::signal<void (U32, const LLSD&)> status_report_signal_t;
+
+ boost::signals2::connection setInitializationErrorCallback(const status_report_signal_t::slot_type& cb);
+ boost::signals2::connection setStatusChangedCallback(const status_changed_signal_t::slot_type& cb);
+ boost::signals2::connection setStatusReportCallback(const status_report_signal_t::slot_type& cb);
+
+ void initialize();
+ bool triggerImport();
+ bool isImportInProgress() const { return mImportInProgress; }
+
+protected:
+ void reinitializeAndTriggerImport();
+ void updateImport();
+
+private:
+ bool mAutoTriggerImport;
+ bool mImportInProgress;
+ bool mInitialized;
+
+ status_report_signal_t * mErrorInitSignal;
+ status_changed_signal_t * mStatusChangedSignal;
+ status_report_signal_t * mStatusReportSignal;
+};
+
+
+
+#endif // LL_LLMARKETPLACEFUNCTIONS_H
+
diff --git a/indra/newview/llmarketplacenotifications.cpp b/indra/newview/llmarketplacenotifications.cpp
new file mode 100644
index 0000000000..0886f9a990
--- /dev/null
+++ b/indra/newview/llmarketplacenotifications.cpp
@@ -0,0 +1,90 @@
+/**
+ * @file llmarketplacenotifications.cpp
+ * @brief Handler for notifications related to marketplace file I/O
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+
+#include "llmarketplacenotifications.h"
+#include "llnotificationsutil.h"
+
+#include "llerror.h"
+
+#include <boost/foreach.hpp>
+#include <boost/signals2.hpp>
+
+
+namespace LLMarketplaceInventoryNotifications
+{
+ typedef boost::signals2::signal<void (const LLSD& param)> no_copy_payload_cb_signal_t;
+
+ static no_copy_payload_cb_signal_t* no_copy_cb_action = NULL;
+ static bool no_copy_notify_active = false;
+ static std::list<LLSD> no_copy_payloads;
+
+ void notifyNoCopyCallback(const LLSD& notification, const LLSD& response)
+ {
+ const S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (option == 0)
+ {
+ llassert(!no_copy_payloads.empty());
+ llassert(no_copy_cb_action != NULL);
+
+ BOOST_FOREACH(const LLSD& payload, no_copy_payloads)
+ {
+ (*no_copy_cb_action)(payload);
+ }
+ }
+
+ delete no_copy_cb_action;
+ no_copy_cb_action = NULL;
+
+ no_copy_notify_active = false;
+ no_copy_payloads.clear();
+ }
+
+ void update()
+ {
+ if (!no_copy_notify_active && !no_copy_payloads.empty())
+ {
+ no_copy_notify_active = true;
+
+ LLNotificationsUtil::add("ConfirmNoCopyToOutbox", LLSD(), LLSD(), boost::bind(&notifyNoCopyCallback, _1, _2));
+ }
+ }
+
+ void addNoCopyNotification(const LLSD& payload, const NoCopyCallbackFunction& cb)
+ {
+ if (no_copy_cb_action == NULL)
+ {
+ no_copy_cb_action = new no_copy_payload_cb_signal_t;
+ no_copy_cb_action->connect(boost::bind(cb, _1));
+ }
+
+ no_copy_payloads.push_back(payload);
+ }
+}
diff --git a/indra/newview/llmarketplacenotifications.h b/indra/newview/llmarketplacenotifications.h
new file mode 100644
index 0000000000..83a4e163c7
--- /dev/null
+++ b/indra/newview/llmarketplacenotifications.h
@@ -0,0 +1,57 @@
+/**
+ * @file llmarketplacenotifications.h
+ * @brief Handler for notifications related to marketplace file I/O
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMARKETPLACENOTIFICATIONS_H
+#define LL_LLMARKETPLACENOTIFICATIONS_H
+
+
+#include <llsd.h>
+#include <boost/function.hpp>
+
+
+//
+// This is a set of helper functions to handle a unique notification with multiple
+// payloads, helpful when dragging and dropping items to the merchant outbox that
+// trigger notifications that can potentially interfere with the current drag and
+// drop operation.
+//
+// Notification payloads are cached locally when initiated, the notification itself
+// is triggered on the following frame during the call to "update" and then the
+// response is triggered once per payload.
+//
+
+namespace LLMarketplaceInventoryNotifications
+{
+ void update();
+
+ typedef boost::function<void (const LLSD&)> NoCopyCallbackFunction;
+
+ void addNoCopyNotification(const LLSD& payload, const NoCopyCallbackFunction& cb);
+};
+
+
+#endif // LL_LLMARKETPLACENOTIFICATIONS_H
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 74fa5d350a..7650fe9229 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -133,10 +133,15 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
navigateHome();
}
- // 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 );
-// addChild( mBorder );
+ LLWindowShade::Params params;
+ params.name = "notification_shade";
+ params.rect = getLocalRect();
+ params.follows.flags = FOLLOWS_ALL;
+ params.modal = true;
+
+ mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
+
+ addChild(mWindowShade);
}
LLMediaCtrl::~LLMediaCtrl()
@@ -1092,39 +1097,28 @@ void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response)
void LLMediaCtrl::showNotification(LLNotificationPtr notify)
{
- delete mWindowShade;
+ LLWindowShade* shade = getChild<LLWindowShade>("notification_shade");
- LLWindowShade::Params params;
- params.name = "notification_shade";
- params.rect = getLocalRect();
- params.follows.flags = FOLLOWS_ALL;
- params.notification = notify;
- params.modal = true;
- //HACK: don't hardcode this
if (notify->getIcon() == "Popup_Caution")
{
- params.bg_image.name = "Yellow_Gradient";
- params.text_color = LLColor4::black;
+ shade->setBackgroundImage(LLUI::getUIImage("Yellow_Gradient"));
+ shade->setTextColor(LLColor4::black);
+ shade->setCanClose(true);
}
- else
- //HACK: another one since XUI doesn't support what we need right now
- if (notify->getName() == "AuthRequest")
+ else if (notify->getName() == "AuthRequest")
{
- params.bg_image.name = "Yellow_Gradient";
- params.text_color = LLColor4::black;
- params.can_close = false;
+ shade->setBackgroundImage(LLUI::getUIImage("Yellow_Gradient"));
+ shade->setTextColor(LLColor4::black);
+ shade->setCanClose(false);
}
else
{
//HACK: make this a property of the notification itself, "cancellable"
- params.can_close = false;
- params.text_color.control = "LabelTextColor";
+ shade->setCanClose(false);
+ shade->setTextColor(LLUIColorTable::instance().getColor("LabelTextColor"));
}
- mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
-
- addChild(mWindowShade);
- mWindowShade->show();
+ mWindowShade->show(notify);
}
void LLMediaCtrl::hideNotification()
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index a97e256c89..b02bf79a28 100644..100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -88,6 +88,9 @@ const S32 MAX_MESH_VERSION = 999;
U32 LLMeshRepository::sBytesReceived = 0;
U32 LLMeshRepository::sHTTPRequestCount = 0;
U32 LLMeshRepository::sHTTPRetryCount = 0;
+U32 LLMeshRepository::sLODProcessing = 0;
+U32 LLMeshRepository::sLODPending = 0;
+
U32 LLMeshRepository::sCacheBytesRead = 0;
U32 LLMeshRepository::sCacheBytesWritten = 0;
U32 LLMeshRepository::sPeakKbps = 0;
@@ -205,6 +208,12 @@ public:
LLMeshHeaderResponder(const LLVolumeParams& mesh_params)
: mMeshParams(mesh_params)
{
+ LLMeshRepoThread::sActiveHeaderRequests++;
+ }
+
+ ~LLMeshHeaderResponder()
+ {
+ LLMeshRepoThread::sActiveHeaderRequests--;
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -224,6 +233,12 @@ public:
LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes)
: mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes)
{
+ LLMeshRepoThread::sActiveLODRequests++;
+ }
+
+ ~LLMeshLODResponder()
+ {
+ LLMeshRepoThread::sActiveLODRequests--;
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -497,10 +512,13 @@ void LLMeshRepoThread::run()
mMutex->lock();
LODRequest req = mLODReqQ.front();
mLODReqQ.pop();
+ LLMeshRepository::sLODProcessing--;
mMutex->unlock();
- if (fetchMeshLOD(req.mMeshParams, req.mLOD))
+ if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit
{
- count++;
+ mMutex->lock();
+ mLODReqQ.push(req) ;
+ mMutex->unlock();
}
}
}
@@ -512,9 +530,11 @@ void LLMeshRepoThread::run()
HeaderRequest req = mHeaderReqQ.front();
mHeaderReqQ.pop();
mMutex->unlock();
- if (fetchMeshHeader(req.mMeshParams))
+ if (!fetchMeshHeader(req.mMeshParams, count))//failed, resubmit
{
- count++;
+ mMutex->lock();
+ mHeaderReqQ.push(req) ;
+ mMutex->unlock();
}
}
}
@@ -603,6 +623,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
{
LLMutexLock lock(mMutex);
mLODReqQ.push(req);
+ LLMeshRepository::sLODProcessing++;
}
}
else
@@ -658,6 +679,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
return false;
}
+ bool ret = true ;
U32 header_size = mMeshHeaderSize[mesh_id];
if (header_size > 0)
@@ -673,7 +695,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
//check VFS for mesh skin info
LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
if (file.getSize() >= offset+size)
- {
+ {
LLMeshRepository::sCacheBytesRead += size;
file.seek(offset);
U8* buffer = new U8[size];
@@ -689,7 +711,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
if (!zero)
{ //attempt to parse
if (skinInfoReceived(mesh_id, buffer, size))
- {
+ {
delete[] buffer;
return true;
}
@@ -704,11 +726,13 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
- {
- ++sActiveLODRequests;
- LLMeshRepository::sHTTPRequestCount++;
- mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size,
+ {
+ ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
new LLMeshSkinInfoResponder(mesh_id, offset, size));
+ if(ret)
+ {
+ LLMeshRepository::sHTTPRequestCount++;
+ }
}
}
}
@@ -718,7 +742,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
}
//early out was not hit, effectively fetched
- return true;
+ return ret;
}
bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
@@ -732,7 +756,8 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
}
U32 header_size = mMeshHeaderSize[mesh_id];
-
+ bool ret = true ;
+
if (header_size > 0)
{
S32 version = mMeshHeader[mesh_id]["version"].asInteger();
@@ -748,6 +773,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesRead += size;
+
file.seek(offset);
U8* buffer = new U8[size];
file.read(buffer, size);
@@ -777,11 +803,13 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
- {
- ++sActiveLODRequests;
- LLMeshRepository::sHTTPRequestCount++;
- mCurlRequest->getByteRange(http_url, headers, offset, size,
+ {
+ ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
new LLMeshDecompositionResponder(mesh_id, offset, size));
+ if(ret)
+ {
+ LLMeshRepository::sHTTPRequestCount++;
+ }
}
}
}
@@ -791,7 +819,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
}
//early out was not hit, effectively fetched
- return true;
+ return ret;
}
bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
@@ -805,6 +833,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
}
U32 header_size = mMeshHeaderSize[mesh_id];
+ bool ret = true ;
if (header_size > 0)
{
@@ -850,11 +879,14 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
- {
- ++sActiveLODRequests;
- LLMeshRepository::sHTTPRequestCount++;
- mCurlRequest->getByteRange(http_url, headers, offset, size,
+ {
+ ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
new LLMeshPhysicsShapeResponder(mesh_id, offset, size));
+
+ if(ret)
+ {
+ LLMeshRepository::sHTTPRequestCount++;
+ }
}
}
else
@@ -868,13 +900,12 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
}
//early out was not hit, effectively fetched
- return true;
+ return ret;
}
-bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
+//return false if failed to get header
+bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count)
{
- bool retval = false;
-
{
//look for mesh in asset in vfs
LLVFile file(gVFS, mesh_params.getSculptID(), LLAssetType::AT_MESH);
@@ -889,36 +920,39 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
file.read(buffer, bytes);
if (headerReceived(mesh_params, buffer, bytes))
{ //did not do an HTTP request, return false
- return false;
+ return true;
}
}
}
- //either cache entry doesn't exist or is corrupt, request header from simulator
-
+ //either cache entry doesn't exist or is corrupt, request header from simulator
+ bool retval = true ;
std::vector<std::string> headers;
headers.push_back("Accept: application/octet-stream");
std::string http_url = constructUrl(mesh_params.getSculptID());
if (!http_url.empty())
{
- ++sActiveHeaderRequests;
- retval = true;
//grab first 4KB if we're going to bother with a fetch. Cache will prevent future fetches if a full mesh fits
//within the first 4KB
- //NOTE -- this will break of headers ever exceed 4KB
- LLMeshRepository::sHTTPRequestCount++;
- mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params));
+ //NOTE -- this will break of headers ever exceed 4KB
+ retval = mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params));
+ if(retval)
+ {
+ LLMeshRepository::sHTTPRequestCount++;
+ }
+ count++;
}
return retval;
}
-bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
+//return false if failed to get mesh lod.
+bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count)
{ //protected by mMutex
mHeaderMutex->lock();
- bool retval = false;
+ bool retval = true;
LLUUID mesh_id = mesh_params.getSculptID();
@@ -955,7 +989,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
if (lodReceived(mesh_params, lod, buffer, size))
{
delete[] buffer;
- return false;
+ return true;
}
}
@@ -968,12 +1002,15 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
- {
- ++sActiveLODRequests;
- retval = true;
- LLMeshRepository::sHTTPRequestCount++;
- mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size,
+ {
+ retval = mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size,
new LLMeshLODResponder(mesh_params, lod, offset, size));
+
+ if(retval)
+ {
+ LLMeshRepository::sHTTPRequestCount++;
+ }
+ count++;
}
else
{
@@ -1045,6 +1082,7 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
{
LODRequest req(mesh_params, iter->second[i]);
mLODReqQ.push(req);
+ LLMeshRepository::sLODProcessing++;
}
}
mPendingLOD.erase(iter);
@@ -1540,8 +1578,17 @@ void LLMeshUploadThread::doWholeModelUpload()
LLSD body = full_model_data["asset_resources"];
dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num));
LLCurlRequest::headers_t headers;
- mCurlRequest->post(mWholeModelUploadURL, headers, body,
- new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle), mMeshUploadTimeOut);
+
+ {
+ LLCurl::ResponderPtr responder = new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle) ;
+
+ while(!mCurlRequest->post(mWholeModelUploadURL, headers, body, responder, mMeshUploadTimeOut))
+ {
+ //sleep for 10ms to prevent eating a whole core
+ apr_sleep(10000);
+ }
+ }
+
do
{
mCurlRequest->process();
@@ -1571,8 +1618,15 @@ void LLMeshUploadThread::requestWholeModelFee()
mPendingUploads++;
LLCurlRequest::headers_t headers;
- mCurlRequest->post(mWholeModelFeeCapability, headers, model_data,
- new LLWholeModelFeeResponder(this,model_data, mFeeObserverHandle), mMeshUploadTimeOut);
+
+ {
+ LLCurl::ResponderPtr responder = new LLWholeModelFeeResponder(this,model_data, mFeeObserverHandle) ;
+ while(!mCurlRequest->post(mWholeModelFeeCapability, headers, model_data, responder, mMeshUploadTimeOut))
+ {
+ //sleep for 10ms to prevent eating a whole core
+ apr_sleep(10000);
+ }
+ }
do
{
@@ -1712,7 +1766,6 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
const LLIOPipe::buffer_ptr_t& buffer)
{
- LLMeshRepoThread::sActiveLODRequests--;
S32 data_size = buffer->countAfter(channels.in(), NULL);
if (status < 200 || status > 400)
@@ -1929,7 +1982,6 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
- LLMeshRepoThread::sActiveHeaderRequests--;
if (status < 200 || status > 400)
{
//llwarns
@@ -2147,6 +2199,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
//first request for this mesh
mLoadingMeshes[detail][mesh_params].insert(vobj->getID());
mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail));
+ LLMeshRepository::sLODPending++;
}
}
@@ -2359,6 +2412,7 @@ void LLMeshRepository::notifyLoadedMeshes()
LLMeshRepoThread::LODRequest& request = mPendingRequests.front();
mThread->loadMeshLOD(request.mMeshParams, request.mLOD);
mPendingRequests.erase(mPendingRequests.begin());
+ LLMeshRepository::sLODPending--;
push_count--;
}
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 31b84ea0d9..da81bb057b 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -323,8 +323,8 @@ public:
virtual void run();
void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
- bool fetchMeshHeader(const LLVolumeParams& mesh_params);
- bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
+ bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count);
+ bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count);
bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
bool lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size);
bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
@@ -441,6 +441,8 @@ public:
static U32 sBytesReceived;
static U32 sHTTPRequestCount;
static U32 sHTTPRetryCount;
+ static U32 sLODPending;
+ static U32 sLODProcessing;
static U32 sCacheBytesRead;
static U32 sCacheBytesWritten;
static U32 sPeakKbps;
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 183063f1db..4512c14b7a 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -48,6 +48,7 @@
#include "llrootview.h"
#include "llviewerchat.h"
#include "llnearbychat.h"
+#include "lltranslate.h"
#include "llresizehandle.h"
@@ -108,6 +109,10 @@ BOOL LLNearbyChatBar::postBuild()
mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
mOutputMonitor->setVisible(FALSE);
+ gSavedSettings.declareBOOL("nearbychat_history_visibility", mNearbyChat->getVisible(), "Visibility state of nearby chat history", TRUE);
+
+ mNearbyChat->setVisible(gSavedSettings.getBOOL("nearbychat_history_visibility"));
+
// Register for font change notifications
LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1));
@@ -116,6 +121,12 @@ BOOL LLNearbyChatBar::postBuild()
return TRUE;
}
+// virtual
+void LLNearbyChatBar::onOpen(const LLSD& key)
+{
+ enableTranslationCheckbox(LLTranslate::isTranslationConfigured());
+}
+
bool LLNearbyChatBar::applyRectControl()
{
bool rect_controlled = LLFloater::applyRectControl();
@@ -159,6 +170,11 @@ void LLNearbyChatBar::showHistory()
}
}
+void LLNearbyChatBar::enableTranslationCheckbox(BOOL enable)
+{
+ getChild<LLUICtrl>("translate_chat_checkbox")->setEnabled(enable);
+}
+
void LLNearbyChatBar::draw()
{
displaySpeakingIndicator();
@@ -401,6 +417,8 @@ void LLNearbyChatBar::onToggleNearbyChatPanel()
enableResizeCtrls(true);
storeRectControl();
}
+
+ gSavedSettings.setBOOL("nearbychat_history_visibility", mNearbyChat->getVisible());
}
void LLNearbyChatBar::setMinimized(BOOL b)
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index c2f57dc4ca..baf12a06ea 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -43,6 +43,7 @@ public:
~LLNearbyChatBar() {}
virtual BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
static LLNearbyChatBar* getInstance();
@@ -60,6 +61,7 @@ public:
static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
void showHistory();
+ void enableTranslationCheckbox(BOOL enable);
/*virtual*/void setMinimized(BOOL b);
protected:
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 28a69f2373..23dbb6b047 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -283,9 +283,17 @@ class LLBrowserNotification : public LLSingleton<LLBrowserNotification>
{
public:
virtual bool processNotification(const LLSD& notify);
+};
+/**
+ * Handler for outbox notifications
+ */
+class LLOutboxNotification : public LLSingleton<LLOutboxNotification>
+{
+public:
+ virtual bool processNotification(const LLSD& notify);
};
-
+
class LLHandlerUtil
{
public:
diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp
index 6988227128..6105eff8ea 100644
--- a/indra/newview/llnotificationmanager.cpp
+++ b/indra/newview/llnotificationmanager.cpp
@@ -62,6 +62,7 @@ void LLNotificationManager::init()
LLNotificationChannel::buildChannel("Offer", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "offer"));
LLNotificationChannel::buildChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint"));
LLNotificationChannel::buildChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser"));
+ LLNotificationChannel::buildChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"));
LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
@@ -72,6 +73,7 @@ void LLNotificationManager::init()
LLNotifications::instance().getChannel("Offer")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
LLNotifications::instance().getChannel("Hints")->connectChanged(boost::bind(&LLHintHandler::processNotification, LLHintHandler::getInstance(), _1));
LLNotifications::instance().getChannel("Browser")->connectChanged(boost::bind(&LLBrowserNotification::processNotification, LLBrowserNotification::getInstance(), _1));
+ LLNotifications::instance().getChannel("Outbox")->connectChanged(boost::bind(&LLOutboxNotification::processNotification, LLOutboxNotification::getInstance(), _1));
mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD()));
mNotifyHandlers["notifytip"] = boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD()));
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index e66dd5690c..363443646d 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -1062,7 +1062,7 @@ void LLGroupMoneyDetailsTabEventHandler::processReply(LLMessageSystem* msg,
// We don't do time zone corrections of the calculated number of seconds
// because we don't have a full time stamp, only a date.
- substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%A %b %d, %Y", start_date);
+ substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%Y-%m-%d", start_date);
LLStringUtil::format (time_str, substitution);
if ( interval_days != mImplementationp->mIntervalLength ||
@@ -1217,7 +1217,7 @@ void LLGroupMoneySalesTabEventHandler::processReply(LLMessageSystem* msg,
// We don't do time zone corrections of the calculated number of seconds
// because we don't have a full time stamp, only a date.
- substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%A %b %d, %Y", start_date);
+ substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%Y-%m-%d", start_date);
LLStringUtil::format (time_str, substitution);
text = time_str + "\n\n";
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 9944b51902..374afb90be 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -28,6 +28,7 @@
#include "llpanelmaininventory.h"
#include "llagent.h"
+#include "llagentcamera.h"
#include "llavataractions.h"
#include "lldndbutton.h"
#include "lleconomy.h"
@@ -294,7 +295,13 @@ void LLPanelMainInventory::closeAllFolders()
void LLPanelMainInventory::newWindow()
{
- LLFloaterInventory::showAgentInventory();
+ static S32 instance_num = 0;
+ instance_num = (instance_num + 1) % S32_MAX;
+
+ if (!gAgentCamera.cameraMouselook())
+ {
+ LLFloaterReg::showTypedInstance<LLFloaterSidePanelContainer>("inventory", LLSD(instance_num));
+ }
}
void LLPanelMainInventory::doCreate(const LLSD& userdata)
@@ -586,7 +593,7 @@ void LLPanelMainInventory::onFocusReceived()
return;
}
- sidepanel_inventory->clearSelections(false, true, true);
+ sidepanel_inventory->clearSelections(false, true);
}
void LLPanelMainInventory::setFilterTextFromFilter()
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 7cb4bbf891..66c9c323cb 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -48,6 +48,8 @@ const LLPanelMarketplaceInbox::Params& LLPanelMarketplaceInbox::getDefaultParams
// protected
LLPanelMarketplaceInbox::LLPanelMarketplaceInbox(const Params& p)
: LLPanel(p)
+ , mFreshCountCtrl(NULL)
+ , mInboxButton(NULL)
, mInventoryPanel(NULL)
{
}
@@ -60,6 +62,9 @@ LLPanelMarketplaceInbox::~LLPanelMarketplaceInbox()
BOOL LLPanelMarketplaceInbox::postBuild()
{
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceInbox::onFocusReceived, this));
+
+ mFreshCountCtrl = getChild<LLUICtrl>("inbox_fresh_new_count");
+ mInboxButton = getChild<LLButton>("inbox_btn");
return TRUE;
}
@@ -109,7 +114,7 @@ void LLPanelMarketplaceInbox::onFocusReceived()
LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
if (sidepanel_inventory)
{
- sidepanel_inventory->clearSelections(true, false, true);
+ sidepanel_inventory->clearSelections(true, false);
}
gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
@@ -216,7 +221,7 @@ void LLPanelMarketplaceInbox::draw()
{
U32 item_count = getTotalItemCount();
- LLView * fresh_new_count_view = getChildView("inbox_fresh_new_count");
+ llassert(mFreshCountCtrl != NULL);
if (item_count > 0)
{
@@ -224,26 +229,26 @@ void LLPanelMarketplaceInbox::draw()
LLStringUtil::format_map_t args;
args["[NUM]"] = item_count_str;
- getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelWithArg", args));
+ mInboxButton->setLabel(getString("InboxLabelWithArg", args));
#if SUPPORTING_FRESH_ITEM_COUNT
// set green text to fresh item count
U32 fresh_item_count = getFreshItemCount();
- fresh_new_count_view->setVisible((fresh_item_count > 0));
+ mFreshCountCtrl->setVisible((fresh_item_count > 0));
if (fresh_item_count > 0)
{
- getChild<LLUICtrl>("inbox_fresh_new_count")->setTextArg("[NUM]", llformat("%d", fresh_item_count));
+ mFreshCountCtrl->setTextArg("[NUM]", llformat("%d", fresh_item_count));
}
#else
- fresh_new_count_view->setVisible(FALSE);
+ mFreshCountCtrl->setVisible(FALSE);
#endif
}
else
{
- getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelNoArg"));
+ mInboxButton->setLabel(getString("InboxLabelNoArg"));
- fresh_new_count_view->setVisible(FALSE);
+ mFreshCountCtrl->setVisible(FALSE);
}
LLPanel::draw();
diff --git a/indra/newview/llpanelmarketplaceinbox.h b/indra/newview/llpanelmarketplaceinbox.h
index 3531518e51..9eb74581a2 100644
--- a/indra/newview/llpanelmarketplaceinbox.h
+++ b/indra/newview/llpanelmarketplaceinbox.h
@@ -29,7 +29,9 @@
#include "llpanel.h"
+class LLButton;
class LLInventoryPanel;
+class LLUICtrl;
class LLPanelMarketplaceInbox : public LLPanel
{
@@ -66,9 +68,10 @@ private:
void onFocusReceived();
private:
- LLInventoryPanel* mInventoryPanel;
+ LLUICtrl * mFreshCountCtrl;
+ LLButton * mInboxButton;
+ LLInventoryPanel * mInventoryPanel;
};
#endif //LL_LLPANELMARKETPLACEINBOX_H
-
diff --git a/indra/newview/llpanelmarketplaceoutbox.cpp b/indra/newview/llpanelmarketplaceoutbox.cpp
deleted file mode 100644
index 12960fd0d6..0000000000
--- a/indra/newview/llpanelmarketplaceoutbox.cpp
+++ /dev/null
@@ -1,363 +0,0 @@
-/**
- * @file llpanelmarketplaceoutbox.cpp
- * @brief Panel for marketplace outbox
- *
-* $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelmarketplaceoutbox.h"
-#include "llpanelmarketplaceoutboxinventory.h"
-
-#include "llappviewer.h"
-#include "llbutton.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llinventorypanel.h"
-#include "llloadingindicator.h"
-#include "llnotificationsutil.h"
-#include "llpanelmarketplaceinbox.h"
-#include "llsdutil.h"
-#include "llsidepanelinventory.h"
-#include "lltimer.h"
-#include "llviewernetwork.h"
-#include "llagent.h"
-#include "llviewermedia.h"
-#include "llfolderview.h"
-#include "llinventoryfunctions.h"
-
-static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox");
-
-const LLPanelMarketplaceOutbox::Params& LLPanelMarketplaceOutbox::getDefaultParams()
-{
- return LLUICtrlFactory::getDefaultParams<LLPanelMarketplaceOutbox>();
-}
-
-// protected
-LLPanelMarketplaceOutbox::LLPanelMarketplaceOutbox(const Params& p)
- : LLPanel(p)
- , mInventoryPanel(NULL)
- , mSyncButton(NULL)
- , mSyncIndicator(NULL)
- , mSyncInProgress(false)
-{
-}
-
-LLPanelMarketplaceOutbox::~LLPanelMarketplaceOutbox()
-{
-}
-
-// virtual
-BOOL LLPanelMarketplaceOutbox::postBuild()
-{
- LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceOutbox::handleLoginComplete, this));
-
- LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceOutbox::onFocusReceived, this));
-
- return TRUE;
-}
-
-void LLPanelMarketplaceOutbox::handleLoginComplete()
-{
- mSyncButton = getChild<LLButton>("outbox_sync_btn");
- mSyncButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onSyncButtonClicked, this));
- mSyncButton->setEnabled(!isOutboxEmpty());
-
- mSyncIndicator = getChild<LLLoadingIndicator>("outbox_sync_indicator");
-}
-
-void LLPanelMarketplaceOutbox::onFocusReceived()
-{
- LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
- if (sidepanel_inventory)
- {
- sidepanel_inventory->clearSelections(true, true, false);
- }
-}
-
-void LLPanelMarketplaceOutbox::onSelectionChange()
-{
- LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
- if (sidepanel_inventory)
- {
- sidepanel_inventory->updateVerbs();
- }
-}
-
-LLInventoryPanel * LLPanelMarketplaceOutbox::setupInventoryPanel()
-{
- LLView * outbox_inventory_placeholder = getChild<LLView>("outbox_inventory_placeholder_panel");
- LLView * outbox_inventory_parent = outbox_inventory_placeholder->getParent();
-
- mInventoryPanel =
- LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml",
- outbox_inventory_parent,
- LLInventoryPanel::child_registry_t::instance());
-
- llassert(mInventoryPanel);
-
- // Reshape the inventory to the proper size
- LLRect inventory_placeholder_rect = outbox_inventory_placeholder->getRect();
- mInventoryPanel->setShape(inventory_placeholder_rect);
-
- // Set the sort order newest to oldest
- mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
- mInventoryPanel->getFilter()->markDefault();
-
- // Set selection callback for proper update of inventory status buttons
- mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceOutbox::onSelectionChange, this));
-
- // Set up the note to display when the outbox is empty
- mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryOutboxNoItems");
-
- // Hide the placeholder text
- outbox_inventory_placeholder->setVisible(FALSE);
-
- return mInventoryPanel;
-}
-
-BOOL LLPanelMarketplaceOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-
- if (!handled && mInventoryPanel && mInventoryPanel->getRootFolder())
- {
- handled = mInventoryPanel->getRootFolder()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
-
- if (handled)
- {
- mInventoryPanel->getRootFolder()->setDragAndDropThisFrame();
- }
- }
-
- return handled;
-}
-
-bool LLPanelMarketplaceOutbox::isOutboxEmpty() const
-{
- return (getTotalItemCount() == 0);
-}
-
-bool LLPanelMarketplaceOutbox::isSyncInProgress() const
-{
- return mSyncInProgress;
-}
-
-
-std::string gTimeDelayDebugFunc = "";
-
-void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel)
-{
- waitForEventOn(self, "mainloop");
-
- LLTimer delayTimer;
- delayTimer.reset();
- delayTimer.setTimerExpirySec(5.0f);
-
- while (!delayTimer.hasExpired())
- {
- waitForEventOn(self, "mainloop");
- }
-
- outboxPanel->onSyncComplete(true, LLSD::emptyMap());
-
- gTimeDelayDebugFunc = "";
-}
-
-
-class LLInventorySyncResponder : public LLHTTPClient::Responder
-{
-public:
- LLInventorySyncResponder(LLPanelMarketplaceOutbox * outboxPanel)
- : LLCurl::Responder()
- , mOutboxPanel(outboxPanel)
- {
- }
-
- void completed(U32 status, const std::string& reason, const LLSD& content)
- {
- llinfos << "inventory_import complete status: " << status << ", reason: " << reason << llendl;
-
- if (isGoodStatus(status))
- {
- // Complete success
- llinfos << "success" << llendl;
- }
- else
- {
- llwarns << "failed" << llendl;
- }
-
- mOutboxPanel->onSyncComplete(isGoodStatus(status), content);
- }
-
-private:
- LLPanelMarketplaceOutbox * mOutboxPanel;
-};
-
-void LLPanelMarketplaceOutbox::onSyncButtonClicked()
-{
- // Get the sync animation going
- mSyncInProgress = true;
- updateSyncButtonStatus();
-
- // Make the url for the inventory import request
- std::string url = "https://marketplace.secondlife.com/";
-
- if (!LLGridManager::getInstance()->isInProductionGrid())
- {
- std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
- url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str());
-
- // TEMP for Jim's pdp
- //url = "http://pdp24.lindenlab.com:3000/";
- }
-
- url += "api/1/users/";
- url += gAgent.getID().getString();
- url += "/inventory_import";
-
- llinfos << "http get: " << url << llendl;
- LLHTTPClient::get(url, new LLInventorySyncResponder(this), LLViewerMedia::getHeaders());
-
- // Set a timer (for testing only)
- //gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this));
-}
-
-void LLPanelMarketplaceOutbox::onSyncComplete(bool goodStatus, const LLSD& content)
-{
- mSyncInProgress = false;
- updateSyncButtonStatus();
-
- const LLSD& errors_list = content["errors"];
-
- if (goodStatus && (errors_list.size() == 0))
- {
- LLNotificationsUtil::add("OutboxUploadComplete", LLSD::emptyMap(), LLSD::emptyMap());
- }
- else
- {
- LLNotificationsUtil::add("OutboxUploadHadErrors", LLSD::emptyMap(), LLSD::emptyMap());
- }
-
- llinfos << "Marketplace upload llsd:" << llendl;
- llinfos << ll_pretty_print_sd(content) << llendl;
- llinfos << llendl;
-
- const LLSD& imported_list = content["imported"];
- LLSD::array_const_iterator it = imported_list.beginArray();
- for ( ; it != imported_list.endArray(); ++it)
- {
- LLUUID imported_folder = (*it).asUUID();
- llinfos << "Successfully uploaded folder " << imported_folder.asString() << " to marketplace." << llendl;
- }
-
- for (it = errors_list.beginArray(); it != errors_list.endArray(); ++it)
- {
- const LLSD& item_error_map = (*it);
-
- LLUUID error_folder = item_error_map["folder_id"].asUUID();
- const std::string& error_string = item_error_map["identifier"].asString();
- LLUUID error_item = item_error_map["item_id"].asUUID();
- const std::string& error_item_name = item_error_map["item_name"].asString();
- const std::string& error_message = item_error_map["message"].asString();
-
- llinfos << "Error item " << error_folder.asString() << ", " << error_string << ", "
- << error_item.asString() << ", " << error_item_name << ", " << error_message << llendl;
-
- LLFolderViewFolder * item_folder = mInventoryPanel->getRootFolder()->getFolderByID(error_folder);
- LLOutboxFolderViewFolder * outbox_item_folder = dynamic_cast<LLOutboxFolderViewFolder *>(item_folder);
-
- llassert(outbox_item_folder);
-
- outbox_item_folder->setErrorString(error_string);
- }
-}
-
-void LLPanelMarketplaceOutbox::updateSyncButtonStatus()
-{
- if (isSyncInProgress())
- {
- mSyncButton->setVisible(false);
-
- mSyncIndicator->setVisible(true);
- mSyncIndicator->reset();
- mSyncIndicator->start();
- }
- else
- {
- mSyncIndicator->stop();
- mSyncIndicator->setVisible(false);
-
- mSyncButton->setVisible(true);
- mSyncButton->setEnabled(!isOutboxEmpty());
- }
-}
-
-U32 LLPanelMarketplaceOutbox::getTotalItemCount() const
-{
- U32 item_count = 0;
-
- if (mInventoryPanel)
- {
- const LLFolderViewFolder * outbox_folder = mInventoryPanel->getRootFolder();
-
- if (outbox_folder)
- {
- item_count += outbox_folder->getFoldersCount();
- }
- }
-
- return item_count;
-}
-
-void LLPanelMarketplaceOutbox::draw()
-{
- const U32 item_count = getTotalItemCount();
- const bool not_empty = (item_count > 0);
-
- if (not_empty)
- {
- std::string item_count_str = llformat("%d", item_count);
-
- LLStringUtil::format_map_t args;
- args["[NUM]"] = item_count_str;
- getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelWithArg", args));
- }
- else
- {
- getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelNoArg"));
- }
-
- if (!isSyncInProgress())
- {
- mSyncButton->setEnabled(not_empty);
- }
-
- LLPanel::draw();
-}
diff --git a/indra/newview/llpanelmarketplaceoutbox.h b/indra/newview/llpanelmarketplaceoutbox.h
deleted file mode 100644
index c6b4a5abe2..0000000000
--- a/indra/newview/llpanelmarketplaceoutbox.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * @file llpanelmarketplaceoutbox.h
- * @brief Panel for marketplace outbox
- *
-* $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLPANELMARKETPLACEOUTBOX_H
-#define LL_LLPANELMARKETPLACEOUTBOX_H
-
-#include "llpanel.h"
-
-
-class LLButton;
-class LLInventoryPanel;
-class LLLoadingIndicator;
-
-
-class LLPanelMarketplaceOutbox : public LLPanel
-{
-public:
-
- struct Params : public LLInitParam::Block<Params, LLPanel::Params>
- {};
-
- LOG_CLASS(LLPanelMarketplaceOutbox);
-
- // RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8
- static const LLPanelMarketplaceOutbox::Params& getDefaultParams();
-
- LLPanelMarketplaceOutbox(const Params& p = getDefaultParams());
- ~LLPanelMarketplaceOutbox();
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void draw();
-
- LLInventoryPanel * setupInventoryPanel();
-
- U32 getTotalItemCount() const;
-
- bool isOutboxEmpty() const;
- bool isSyncInProgress() const;
-
- void onSyncComplete(bool goodStatus, const LLSD& content);
-
- /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
-
-protected:
- void onSyncButtonClicked();
- void updateSyncButtonStatus();
-
- void handleLoginComplete();
- void onFocusReceived();
- void onSelectionChange();
-
-private:
- LLInventoryPanel * mInventoryPanel;
-
- LLButton * mSyncButton;
- LLLoadingIndicator * mSyncIndicator;
- bool mSyncInProgress;
-};
-
-
-#endif //LL_LLPANELMARKETPLACEOUTBOX_H
-
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
index ed1206aec8..ff62cb23db 100644
--- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
@@ -47,50 +47,6 @@ static LLDefaultChildRegistry::Register<LLOutboxFolderViewFolder> r2("outbox_fol
//
-// Marketplace errors
-//
-
-enum
-{
- MKTERR_NONE = 0,
-
- MKTERR_NOT_MERCHANT,
- MKTERR_FOLDER_EMPTY,
- MKTERR_UNASSOCIATED_PRODUCTS,
- MKTERR_OBJECT_LIMIT,
- MKTERR_FOLDER_DEPTH,
- MKTERR_UNSELLABLE_ITEM,
- MKTERR_INTERNAL_IMPORT,
-
- MKTERR_COUNT
-};
-
-static const std::string MARKETPLACE_ERROR_STRINGS[MKTERR_COUNT] =
-{
- "NO_ERROR",
- "NOT_MERCHANT_ERROR",
- "FOLDER_EMPTY_ERROR",
- "UNASSOCIATED_PRODUCTS_ERROR",
- "OBJECT_LIMIT_ERROR",
- "FOLDER_DEPTH_ERROR",
- "UNSELLABLE_ITEM_FOUND",
- "INTERNAL_IMPORT_ERROR",
-};
-
-static const std::string MARKETPLACE_ERROR_NAMES[MKTERR_COUNT] =
-{
- "Marketplace Error None",
- "Marketplace Error Not Merchant",
- "Marketplace Error Empty Folder",
- "Marketplace Error Unassociated Products",
- "Marketplace Error Object Limit",
- "Marketplace Error Folder Depth",
- "Marketplace Error Unsellable Item",
- "Marketplace Error Internal Import",
-};
-
-
-//
// LLOutboxInventoryPanel Implementation
//
@@ -111,37 +67,6 @@ void LLOutboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& par
LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
- // leslie -- temporary HACK to work around sim not creating outbox with proper system folder type
- if (root_id.isNull())
- {
- std::string start_folder_name(params.start_folder());
-
- LLInventoryModel::cat_array_t* cats;
- LLInventoryModel::item_array_t* items;
-
- gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
-
- if (cats)
- {
- for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
- {
- LLInventoryCategory* cat = *cat_it;
-
- if (cat->getName() == start_folder_name)
- {
- root_id = cat->getUUID();
- break;
- }
- }
- }
-
- if (root_id == LLUUID::null)
- {
- llwarns << "No category found that matches outbox inventory panel start_folder: " << start_folder_name << llendl;
- }
- }
- // leslie -- end temporary HACK
-
if (root_id == LLUUID::null)
{
llwarns << "Outbox inventory panel has no root folder!" << llendl;
@@ -206,66 +131,26 @@ LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge *
LLOutboxFolderViewFolder::LLOutboxFolderViewFolder(const Params& p)
: LLFolderViewFolder(p)
- , LLBadgeOwner(getHandle())
- , mError(0)
-{
- initBadgeParams(p.error_badge());
-}
-
-LLOutboxFolderViewFolder::~LLOutboxFolderViewFolder()
{
}
-// virtual
-void LLOutboxFolderViewFolder::draw()
-{
- if (!badgeHasParent())
- {
- addBadgeToParentPanel();
- }
-
- setBadgeVisibility(hasError());
-
- LLFolderViewFolder::draw();
-}
+//
+// LLOutboxFolderViewItem Implementation
+//
-void LLOutboxFolderViewFolder::setErrorString(const std::string& errorString)
+LLOutboxFolderViewItem::LLOutboxFolderViewItem(const Params& p)
+ : LLFolderViewItem(p)
{
- S32 error_code = MKTERR_NONE;
-
- for (S32 i = 1; i < MKTERR_COUNT; ++i)
- {
- if (MARKETPLACE_ERROR_STRINGS[i] == errorString)
- {
- error_code = i;
- break;
- }
- }
-
- setError(error_code);
}
-void LLOutboxFolderViewFolder::setError(S32 errorCode)
+BOOL LLOutboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
{
- mError = errorCode;
-
- if (hasError())
- {
- setToolTip(LLTrans::getString(MARKETPLACE_ERROR_NAMES[mError]));
- }
- else
- {
- setToolTip(LLStringExplicit(""));
- }
+ return TRUE;
}
-//
-// LLOutboxFolderViewItem Implementation
-//
-
-BOOL LLOutboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
+void LLOutboxFolderViewItem::openItem()
{
- return TRUE;
+ // Intentionally do nothing to block attaching items from the outbox
}
// eof
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.h b/indra/newview/llpanelmarketplaceoutboxinventory.h
index 346680a79d..a6c522b7c2 100644
--- a/indra/newview/llpanelmarketplaceoutboxinventory.h
+++ b/indra/newview/llpanelmarketplaceoutboxinventory.h
@@ -28,7 +28,6 @@
#define LL_OUTBOXINVENTORYPANEL_H
-#include "llbadgeowner.h"
#include "llinventorypanel.h"
#include "llfolderviewitem.h"
@@ -53,44 +52,26 @@ public:
};
-class LLOutboxFolderViewFolder : public LLFolderViewFolder, public LLBadgeOwner
+class LLOutboxFolderViewFolder : public LLFolderViewFolder
{
public:
struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
{
- Optional<LLBadge::Params> error_badge;
-
- Params()
- : error_badge("error_badge")
- {
- }
+ Params() {}
};
LLOutboxFolderViewFolder(const Params& p);
- ~LLOutboxFolderViewFolder();
-
- void draw();
-
- void setErrorString(const std::string& errorString);
- void setError(S32 errorCode);
-
- bool hasError() const { return (mError != 0); }
-
-protected:
- S32 mError;
};
class LLOutboxFolderViewItem : public LLFolderViewItem
{
public:
- LLOutboxFolderViewItem(const Params& p)
- : LLFolderViewItem(p)
- {
- }
+ LLOutboxFolderViewItem(const Params& p);
// virtual
BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+ void openItem();
};
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index d5e289e6e6..9c46f04abf 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -526,11 +526,11 @@ LLPanelPeople::~LLPanelPeople()
LLVoiceClient::getInstance()->removeObserver(this);
}
- delete mGroupPlusMenuHandle.get();
- delete mNearbyViewSortMenuHandle.get();
- delete mFriendsViewSortMenuHandle.get();
- delete mGroupsViewSortMenuHandle.get();
- delete mRecentViewSortMenuHandle.get();
+ if (mGroupPlusMenuHandle.get()) mGroupPlusMenuHandle.get()->die();
+ if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die();
+ if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die();
+ if (mGroupsViewSortMenuHandle.get()) mGroupsViewSortMenuHandle.get()->die();
+ if (mRecentViewSortMenuHandle.get()) mRecentViewSortMenuHandle.get()->die();
}
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 933b40ec79..39c0628cbe 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -1351,7 +1351,6 @@ void LLPanelPrimMediaControls::showNotification(LLNotificationPtr notify)
LLWindowShade::Params params;
params.rect = mMediaRegion->getLocalRect();
params.follows.flags = FOLLOWS_ALL;
- params.notification = notify;
//HACK: don't hardcode this
if (notify->getIcon() == "Popup_Caution")
@@ -1369,7 +1368,7 @@ void LLPanelPrimMediaControls::showNotification(LLNotificationPtr notify)
mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
mMediaRegion->addChild(mWindowShade);
- mWindowShade->show();
+ mWindowShade->show(notify);
}
void LLPanelPrimMediaControls::hideNotification()
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index b1eeabb028..e2e7006773 100755
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -177,7 +177,7 @@ LLPanelProfile::ChildStack::~ChildStack()
LLView* viewp = *it;
if (viewp)
{
- delete viewp;
+ viewp->die();
}
}
mStack.pop_back();
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index d3543daff0..1f1cccad85 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -388,7 +388,7 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()
LLTeleportHistoryPanel::~LLTeleportHistoryPanel()
{
LLTeleportHistoryFlatItemStorage::instance().purge();
- delete mGearMenuHandle.get();
+ if (mGearMenuHandle.get()) mGearMenuHandle.get()->die();
mTeleportHistoryChangedConnection.disconnect();
}
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index b19bf5d234..88727bf59b 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -35,6 +35,7 @@
#include "llcombobox.h"
#include "lldir.h"
#include "llexternaleditor.h"
+#include "llfilepicker.h"
#include "llfloaterreg.h"
#include "llinventorydefines.h"
#include "llinventorymodel.h"
@@ -503,6 +504,14 @@ void LLScriptEdCore::initMenu()
menuItem = getChild<LLMenuItemCallGL>("Keyword Help...");
menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnDynamicHelp, this));
+
+ menuItem = getChild<LLMenuItemCallGL>("LoadFromFile");
+ menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnLoadFromFile, this));
+ menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::enableLoadFromFileMenu, this));
+
+ menuItem = getChild<LLMenuItemCallGL>("SaveToFile");
+ menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnSaveToFile, this));
+ menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::enableSaveToFileMenu, this));
}
void LLScriptEdCore::setScriptText(const std::string& text, BOOL is_valid)
@@ -1096,6 +1105,88 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask)
return FALSE;
}
+void LLScriptEdCore::onBtnLoadFromFile( void* data )
+{
+ LLScriptEdCore* self = (LLScriptEdCore*) data;
+
+ // TODO Maybe add a dialogue warning here if the current file has unsaved changes.
+ LLFilePicker& file_picker = LLFilePicker::instance();
+ if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_SCRIPT ) )
+ {
+ //File picking cancelled by user, so nothing to do.
+ return;
+ }
+
+ std::string filename = file_picker.getFirstFile();
+
+ std::ifstream fin(filename.c_str());
+
+ std::string line;
+ std::string text;
+ std::string linetotal;
+ while (!fin.eof())
+ {
+ getline(fin,line);
+ text += line;
+ if (!fin.eof())
+ {
+ text += "\n";
+ }
+ }
+ fin.close();
+
+ // Only replace the script if there is something to replace with.
+ if (text.length() > 0)
+ {
+ self->mEditor->selectAll();
+ LLWString script(utf8str_to_wstring(text));
+ self->mEditor->insertText(script);
+ }
+}
+
+void LLScriptEdCore::onBtnSaveToFile( void* userdata )
+{
+
+ LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT );
+
+ LLScriptEdCore* self = (LLScriptEdCore*) userdata;
+
+ if( self->mSaveCallback )
+ {
+ LLFilePicker& file_picker = LLFilePicker::instance();
+ if( file_picker.getSaveFile( LLFilePicker::FFSAVE_SCRIPT ) )
+ {
+ std::string filename = file_picker.getFirstFile();
+ std::string scriptText=self->mEditor->getText();
+ std::ofstream fout(filename.c_str());
+ fout<<(scriptText);
+ fout.close();
+ self->mSaveCallback( self->mUserdata, FALSE );
+ }
+ }
+}
+
+bool LLScriptEdCore::canLoadOrSaveToFile( void* userdata )
+{
+ LLScriptEdCore* self = (LLScriptEdCore*) userdata;
+ return self->mEditor->canLoadOrSaveToFile();
+}
+
+// static
+bool LLScriptEdCore::enableSaveToFileMenu(void* userdata)
+{
+ LLScriptEdCore* self = (LLScriptEdCore*)userdata;
+ if (!self || !self->mEditor) return FALSE;
+ return self->mEditor->canLoadOrSaveToFile();
+}
+
+// static
+bool LLScriptEdCore::enableLoadFromFileMenu(void* userdata)
+{
+ LLScriptEdCore* self = (LLScriptEdCore*)userdata;
+ return (self && self->mEditor) ? self->mEditor->canLoadOrSaveToFile() : FALSE;
+}
+
/// ---------------------------------------------------------------------------
/// LLScriptEdContainer
/// ---------------------------------------------------------------------------
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index f86be615c4..7563cecd9d 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -79,6 +79,7 @@ public:
/*virtual*/ BOOL postBuild();
BOOL canClose();
void setEnableEditing(bool enable);
+ bool canLoadOrSaveToFile( void* userdata );
void setScriptText(const std::string& text, BOOL is_valid);
bool loadScriptText(const std::string& filename);
@@ -98,6 +99,11 @@ public:
static void onClickForward(void* userdata);
static void onBtnInsertSample(void*);
static void onBtnInsertFunction(LLUICtrl*, void*);
+ static void onBtnLoadFromFile(void*);
+ static void onBtnSaveToFile(void*);
+
+ static bool enableSaveToFileMenu(void* userdata);
+ static bool enableLoadFromFileMenu(void* userdata);
virtual bool hasAccelerators() const { return true; }
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index 85a7e75271..6f98be1cb8 100644
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -408,9 +408,16 @@ void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id)
}
// remove related chiclet
- LLChicletBar::getInstance()->getChicletPanel()->removeChiclet(notification_id);
+ if (LLChicletBar::instanceExists())
+ {
+ LLChicletBar::getInstance()->getChicletPanel()->removeChiclet(notification_id);
+ }
- LLIMWellWindow::getInstance()->removeObjectRow(notification_id);
+ LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance();
+ if (im_well_window)
+ {
+ im_well_window->removeObjectRow(notification_id);
+ }
mNotifications.erase(notification_id);
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 5d0d1ef9a3..6111255a66 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -5556,38 +5556,37 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power)
//helper function for pushing relevant vertices from drawable to GL
void pushWireframe(LLDrawable* drawable)
{
- if (drawable->isState(LLDrawable::RIGGED))
- { //render straight from rigged volume if this is a rigged attachment
- LLVOVolume* vobj = drawable->getVOVolume();
- if (vobj)
- {
- vobj->updateRiggedVolume();
- LLRiggedVolume* rigged_volume = vobj->getRiggedVolume();
- if (rigged_volume)
- {
- LLVertexBuffer::unbind();
- gGL.pushMatrix();
- gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
- for (S32 i = 0; i < rigged_volume->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = rigged_volume->getVolumeFace(i);
- LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices);
- }
- gGL.popMatrix();
- }
- }
- }
- else
+ LLVOVolume* vobj = drawable->getVOVolume();
+ if (vobj)
{
- for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ LLVertexBuffer::unbind();
+ gGL.pushMatrix();
+ gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
+
+ LLVolume* volume = NULL;
+
+ if (drawable->isState(LLDrawable::RIGGED))
+ {
+ vobj->updateRiggedVolume();
+ volume = vobj->getRiggedVolume();
+ }
+ else
+ {
+ volume = vobj->getVolume();
+ }
+
+ if (volume)
{
- LLFace* face = drawable->getFace(i);
- if (face->verify())
+ for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
- pushVerts(face, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
+ const LLVolumeFace& face = volume->getVolumeFace(i);
+ LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices);
}
}
+
+ gGL.popMatrix();
}
+
}
void LLSelectNode::renderOneWireframe(const LLColor4& color)
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 9d069c3996..038b18afbd 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -47,7 +47,6 @@
#include "lloutfitobserver.h"
#include "llpanelmaininventory.h"
#include "llpanelmarketplaceinbox.h"
-#include "llpanelmarketplaceoutbox.h"
#include "llselectmgr.h"
#include "llsidepaneliteminfo.h"
#include "llsidepaneltaskinfo.h"
@@ -68,35 +67,22 @@ static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_
// No longer want the inbox panel to auto-expand since it creates issues with the "new" tag time stamp
#define AUTO_EXPAND_INBOX 0
-// Temporarily disabling the outbox until we straighten out the API
-#define ENABLE_MERCHANT_OUTBOX_PANEL 0 // keep in sync with ENABLE_INVENTORY_DISPLAY_OUTBOX, ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
-
static const char * const INBOX_BUTTON_NAME = "inbox_btn";
-static const char * const OUTBOX_BUTTON_NAME = "outbox_btn";
-
static const char * const INBOX_LAYOUT_PANEL_NAME = "inbox_layout_panel";
-static const char * const OUTBOX_LAYOUT_PANEL_NAME = "outbox_layout_panel";
-
-static const char * const INBOX_OUTBOX_LAYOUT_PANEL_NAME = "inbox_outbox_layout_panel";
static const char * const MAIN_INVENTORY_LAYOUT_PANEL_NAME = "main_inventory_layout_panel";
-static const char * const INBOX_INVENTORY_PANEL = "inventory_inbox";
-static const char * const OUTBOX_INVENTORY_PANEL = "inventory_outbox";
-
-static const char * const INBOX_OUTBOX_LAYOUT_STACK_NAME = "inbox_outbox_layout_stack";
static const char * const INVENTORY_LAYOUT_STACK_NAME = "inventory_layout_stack";
static const char * const MARKETPLACE_INBOX_PANEL = "marketplace_inbox";
-static const char * const MARKETPLACE_OUTBOX_PANEL = "marketplace_outbox";
//
// Helpers
//
-class LLInboxOutboxAddedObserver : public LLInventoryCategoryAddedObserver
+class LLInboxAddedObserver : public LLInventoryCategoryAddedObserver
{
public:
- LLInboxOutboxAddedObserver(LLSidepanelInventory * sidepanelInventory)
+ LLInboxAddedObserver(LLSidepanelInventory * sidepanelInventory)
: LLInventoryCategoryAddedObserver()
, mSidepanelInventory(sidepanelInventory)
{
@@ -116,10 +102,6 @@ public:
mSidepanelInventory->enableInbox(true);
mSidepanelInventory->observeInboxModifications(added_category->getUUID());
break;
- case LLFolderType::FT_OUTBOX:
- mSidepanelInventory->enableOutbox(true);
- mSidepanelInventory->observeOutboxModifications(added_category->getUUID());
- break;
default:
break;
}
@@ -138,12 +120,10 @@ LLSidepanelInventory::LLSidepanelInventory()
: LLPanel()
, mItemPanel(NULL)
, mInventoryPanelInbox(NULL)
- , mInventoryPanelOutbox(NULL)
, mPanelMainInventory(NULL)
, mInboxEnabled(false)
- , mOutboxEnabled(false)
, mCategoriesObserver(NULL)
- , mInboxOutboxAddedObserver(NULL)
+ , mInboxAddedObserver(NULL)
{
//buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
}
@@ -156,11 +136,11 @@ LLSidepanelInventory::~LLSidepanelInventory()
}
delete mCategoriesObserver;
- if (mInboxOutboxAddedObserver && gInventory.containsObserver(mInboxOutboxAddedObserver))
+ if (mInboxAddedObserver && gInventory.containsObserver(mInboxAddedObserver))
{
- gInventory.removeObserver(mInboxOutboxAddedObserver);
+ gInventory.removeObserver(mInboxAddedObserver);
}
- delete mInboxOutboxAddedObserver;
+ delete mInboxAddedObserver;
}
void handleInventoryDisplayInboxChanged()
@@ -172,15 +152,6 @@ void handleInventoryDisplayInboxChanged()
}
}
-void handleInventoryDisplayOutboxChanged()
-{
- LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
- if (sidepanel_inventory)
- {
- sidepanel_inventory->enableOutbox(gSavedSettings.getBOOL("InventoryDisplayOutbox"));
- }
-}
-
BOOL LLSidepanelInventory::postBuild()
{
// UI elements from inventory panel
@@ -242,43 +213,27 @@ BOOL LLSidepanelInventory::postBuild()
}
}
- // Marketplace inbox/outbox setup
+ // Received items inbox setup
{
LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
- // Disable user_resize on main inventory panel by default
- inv_stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, false);
- inv_stack->setPanelUserResize(INBOX_OUTBOX_LAYOUT_PANEL_NAME, false);
-
- // Collapse marketplace panel by default
- inv_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME), true);
-
- LLLayoutStack* inout_stack = getChild<LLLayoutStack>(INBOX_OUTBOX_LAYOUT_STACK_NAME);
-
- // Collapse both inbox and outbox panels
- inout_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), true);
- inout_stack->collapsePanel(getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME), true);
+ // Collapse inbox panel
+ inv_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), true);
// Set up button states and callbacks
LLButton * inbox_button = getChild<LLButton>(INBOX_BUTTON_NAME);
- LLButton * outbox_button = getChild<LLButton>(OUTBOX_BUTTON_NAME);
inbox_button->setToggleState(false);
- outbox_button->setToggleState(false);
-
inbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this));
- outbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleOutboxBtn, this));
- // Set the inbox and outbox visible based on debug settings (final setting comes from http request below)
+ // Set the inbox visible based on debug settings (final setting comes from http request below)
enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));
- enableOutbox(gSavedSettings.getBOOL("InventoryDisplayOutbox"));
- // Trigger callback for after login so we can setup to track inbox and outbox changes after initial inventory load
- LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::updateInboxOutbox, this));
+ // Trigger callback for after login so we can setup to track inbox changes after initial inventory load
+ LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::updateInbox, this));
}
gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged));
- gSavedSettings.getControl("InventoryDisplayOutbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayOutboxChanged));
// Update the verbs buttons state.
updateVerbs();
@@ -286,168 +241,96 @@ BOOL LLSidepanelInventory::postBuild()
return TRUE;
}
-void LLSidepanelInventory::updateInboxOutbox()
+void LLSidepanelInventory::updateInbox()
{
//
- // Track inbox and outbox folder changes
+ // Track inbox folder changes
//
const bool do_not_create_folder = false;
const bool do_not_find_in_library = false;
const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder, do_not_find_in_library);
- const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library);
- // Set up observer to listen for creation of inbox and outbox if at least one of them doesn't exist
- if (inbox_id.isNull() || outbox_id.isNull())
+ // Set up observer to listen for creation of inbox if at least one of them doesn't exist
+ if (inbox_id.isNull())
{
- observeInboxOutboxCreation();
+ observeInboxCreation();
}
-
// Set up observer for inbox changes, if we have an inbox already
- if (!inbox_id.isNull())
+ else
{
// Enable the display of the inbox if it exists
enableInbox(true);
observeInboxModifications(inbox_id);
}
-
-#if ENABLE_MERCHANT_OUTBOX_PANEL
- // Set up observer for outbox changes, if we have an outbox already
- if (!outbox_id.isNull())
- {
- // Enable the display of the outbox if it exists
- enableOutbox(true);
-
- observeOutboxModifications(outbox_id);
- }
-#endif
}
-void LLSidepanelInventory::observeInboxOutboxCreation()
+void LLSidepanelInventory::observeInboxCreation()
{
//
- // Set up observer to track inbox and outbox folder creation
+ // Set up observer to track inbox folder creation
//
- if (mInboxOutboxAddedObserver == NULL)
+ if (mInboxAddedObserver == NULL)
{
- mInboxOutboxAddedObserver = new LLInboxOutboxAddedObserver(this);
+ mInboxAddedObserver = new LLInboxAddedObserver(this);
- gInventory.addObserver(mInboxOutboxAddedObserver);
+ gInventory.addObserver(mInboxAddedObserver);
}
}
void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
{
//
- // Track inbox and outbox folder changes
+ // Silently do nothing if we already have an inbox inventory panel set up
+ // (this can happen multiple times on the initial session that creates the inbox)
//
-
+
+ if (mInventoryPanelInbox != NULL)
+ {
+ return;
+ }
+
+ //
+ // Track inbox folder changes
+ //
+
if (inboxID.isNull())
{
- llwarns << "Attempting to track modifications to non-existant inbox" << llendl;
+ llwarns << "Attempting to track modifications to non-existent inbox" << llendl;
return;
}
-
+
if (mCategoriesObserver == NULL)
{
mCategoriesObserver = new LLInventoryCategoriesObserver();
gInventory.addObserver(mCategoriesObserver);
}
-
+
mCategoriesObserver->addCategory(inboxID, boost::bind(&LLSidepanelInventory::onInboxChanged, this, inboxID));
-
+
//
// Trigger a load for the entire contents of the Inbox
//
-
+
LLInventoryModelBackgroundFetch::instance().start(inboxID);
-
+
//
// Set up the inbox inventory view
//
-
+
LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
mInventoryPanelInbox = inbox->setupInventoryPanel();
}
-
-void LLSidepanelInventory::observeOutboxModifications(const LLUUID& outboxID)
-{
- //
- // Track outbox folder changes
- //
-
- if (outboxID.isNull())
- {
- llwarns << "Attempting to track modifications to non-existant outbox" << llendl;
- return;
- }
-
- if (mCategoriesObserver == NULL)
- {
- mCategoriesObserver = new LLInventoryCategoriesObserver();
- gInventory.addObserver(mCategoriesObserver);
- }
-
- mCategoriesObserver->addCategory(outboxID, boost::bind(&LLSidepanelInventory::onOutboxChanged, this, outboxID));
-
- //
- // Set up the outbox inventory view
- //
-
- LLPanelMarketplaceOutbox * outbox = getChild<LLPanelMarketplaceOutbox>(MARKETPLACE_OUTBOX_PANEL);
- mInventoryPanelOutbox = outbox->setupInventoryPanel();
-}
-
void LLSidepanelInventory::enableInbox(bool enabled)
{
mInboxEnabled = enabled;
LLLayoutPanel * inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
inbox_layout_panel->setVisible(enabled);
-
- if (mInboxEnabled)
- {
- LLLayoutPanel * inout_layout_panel = getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME);
-
- inout_layout_panel->setVisible(TRUE);
-
- if (mOutboxEnabled)
- {
- S32 inbox_min_dim = inbox_layout_panel->getMinDim();
- S32 outbox_min_dim = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME)->getMinDim();
-
- inout_layout_panel->setMinDim(inbox_min_dim + outbox_min_dim);
- }
- }
-}
-
-void LLSidepanelInventory::enableOutbox(bool enabled)
-{
- mOutboxEnabled = enabled;
-
- LLLayoutPanel * outbox_layout_panel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
- outbox_layout_panel->setVisible(enabled);
-
- if (mOutboxEnabled)
- {
- LLLayoutPanel * inout_layout_panel = getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME);
-
- inout_layout_panel->setVisible(TRUE);
-
- if (mInboxEnabled)
- {
- S32 inbox_min_dim = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME)->getMinDim();
- S32 outbox_min_dim = outbox_layout_panel->getMinDim();
-
- inout_layout_panel->setMinDim(inbox_min_dim + outbox_min_dim);
- }
-
- updateOutboxUserStatus();
- }
}
void LLSidepanelInventory::openInbox()
@@ -459,31 +342,13 @@ void LLSidepanelInventory::openInbox()
}
}
-void LLSidepanelInventory::openOutbox()
-{
- if (mOutboxEnabled)
- {
- getChild<LLButton>(OUTBOX_BUTTON_NAME)->setToggleState(true);
- onToggleOutboxBtn();
- }
-}
-
void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id)
{
// Trigger a load of the entire inbox so we always know the contents and their creation dates for sorting
LLInventoryModelBackgroundFetch::instance().start(inbox_id);
#if AUTO_EXPAND_INBOX
- // If the outbox is expanded, don't auto-expand the inbox
- if (mOutboxEnabled)
- {
- if (getChild<LLButton>(OUTBOX_BUTTON_NAME)->getToggleState())
- {
- return;
- }
- }
-
- // Expand the inbox since we have fresh items and the outbox is not expanded
+ // Expand the inbox since we have fresh items
if (mInboxEnabled)
{
getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
@@ -492,68 +357,16 @@ void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id)
#endif
}
-void LLSidepanelInventory::onOutboxChanged(const LLUUID& outbox_id)
-{
- // Expand the outbox since we have new items in it
- if (mOutboxEnabled)
- {
- getChild<LLButton>(OUTBOX_BUTTON_NAME)->setToggleState(true);
- onToggleOutboxBtn();
- }
-}
-
-bool LLSidepanelInventory::manageInboxOutboxPanels(LLButton * pressedButton, LLLayoutPanel * pressedPanel,
- LLButton * otherButton, LLLayoutPanel * otherPanel)
-{
- bool expand = pressedButton->getToggleState();
- bool otherExpanded = otherButton->getToggleState();
-
- LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
- LLLayoutStack* inout_stack = getChild<LLLayoutStack>(INBOX_OUTBOX_LAYOUT_STACK_NAME);
- LLLayoutPanel* inout_panel = getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME);
-
- // Enable user_resize on main inventory panel only when a marketplace box is expanded
- inv_stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, expand);
- inv_stack->collapsePanel(inout_panel, !expand);
-
- // Collapse other marketplace panel if it is expanded
- if (expand && otherExpanded)
- {
- // Reshape pressedPanel to the otherPanel's height so we preserve the marketplace panel size
- pressedPanel->reshape(pressedPanel->getRect().getWidth(), otherPanel->getRect().getHeight());
-
- inout_stack->collapsePanel(otherPanel, true);
- otherButton->setToggleState(false);
- }
- else
- {
- // NOTE: This is an attempt to reshape the inventory panel to the proper size but it doesn't seem to propagate
- // properly to the child panels.
-
- S32 new_height = inout_panel->getRect().getHeight();
-
- if (otherPanel->getVisible())
- {
- new_height -= otherPanel->getMinDim();
- }
-
- pressedPanel->reshape(pressedPanel->getRect().getWidth(), new_height);
- }
-
- // Expand/collapse the indicated panel
- inout_stack->collapsePanel(pressedPanel, !expand);
-
- return expand;
-}
-
void LLSidepanelInventory::onToggleInboxBtn()
{
LLButton* inboxButton = getChild<LLButton>(INBOX_BUTTON_NAME);
LLLayoutPanel* inboxPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
- LLButton* outboxButton = getChild<LLButton>(OUTBOX_BUTTON_NAME);
- LLLayoutPanel* outboxPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
-
- const bool inbox_expanded = manageInboxOutboxPanels(inboxButton, inboxPanel, outboxButton, outboxPanel);
+ LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
+
+ const bool inbox_expanded = inboxButton->getToggleState();
+
+ // Expand/collapse the indicated panel
+ inv_stack->collapsePanel(inboxPanel, !inbox_expanded);
if (inbox_expanded && inboxPanel->isInVisibleChain())
{
@@ -561,16 +374,6 @@ void LLSidepanelInventory::onToggleInboxBtn()
}
}
-void LLSidepanelInventory::onToggleOutboxBtn()
-{
- LLButton* inboxButton = getChild<LLButton>(INBOX_BUTTON_NAME);
- LLLayoutPanel* inboxPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
- LLButton* outboxButton = getChild<LLButton>(OUTBOX_BUTTON_NAME);
- LLLayoutPanel* outboxPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
-
- manageInboxOutboxPanels(outboxButton, outboxPanel, inboxButton, inboxPanel);
-}
-
void LLSidepanelInventory::onOpen(const LLSD& key)
{
LLFirstUse::newInventory(false);
@@ -740,77 +543,6 @@ void LLSidepanelInventory::showInventoryPanel()
updateVerbs();
}
-void LLSidepanelInventory::updateOutboxUserStatus()
-{
- const bool isMerchant = (gSavedSettings.getString("InventoryMarketplaceUserStatus") == "merchant");
- const bool hasOutbox = !gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false).isNull();
-
- LLView * outbox_placeholder = getChild<LLView>("outbox_inventory_placeholder_panel");
- LLView * outbox_placeholder_parent = outbox_placeholder->getParent();
-
- LLTextBox * outbox_title_box = outbox_placeholder->getChild<LLTextBox>("outbox_inventory_placeholder_title");
- LLTextBox * outbox_text_box = outbox_placeholder->getChild<LLTextBox>("outbox_inventory_placeholder_text");
-
- std::string outbox_text;
- std::string outbox_title;
- std::string outbox_tooltip;
-
- if (isMerchant)
- {
- if (hasOutbox)
- {
- outbox_text = LLTrans::getString("InventoryOutboxNoItems");
- outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle");
- outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip");
- }
- else
- {
- outbox_text = LLTrans::getString("InventoryOutboxCreationError");
- outbox_title = LLTrans::getString("InventoryOutboxCreationErrorTitle");
- outbox_tooltip = LLTrans::getString("InventoryOutboxCreationErrorTooltip");
- }
- }
- else
- {
- //
- // The string to become a merchant contains 3 URL's which need the domain name patched in.
- //
-
- std::string domain = "secondlife.com";
-
- if (!LLGridManager::getInstance()->isInProductionGrid())
- {
- std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
- domain = llformat("%s.lindenlab.com", utf8str_tolower(gridLabel).c_str());
- }
-
- LLStringUtil::format_map_t domain_arg;
- domain_arg["[DOMAIN_NAME]"] = domain;
-
- std::string marketplace_url = LLTrans::getString("MarketplaceURL", domain_arg);
- std::string marketplace_url_create = LLTrans::getString("MarketplaceURL_CreateStore", domain_arg);
- std::string marketplace_url_info = LLTrans::getString("MarketplaceURL_LearnMore", domain_arg);
-
- LLStringUtil::format_map_t args1, args2, args3;
- args1["[MARKETPLACE_URL]"] = marketplace_url;
- args2["[LEARN_MORE_URL]"] = marketplace_url_info;
- args3["[CREATE_STORE_URL]"] = marketplace_url_create;
-
- // NOTE: This is dumb, ridiculous and very finicky. The order of these is very important
- // to have these three string substitutions work properly.
- outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", args1);
- LLStringUtil::format(outbox_text, args2);
- LLStringUtil::format(outbox_text, args3);
-
- outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle");
- outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip");
- }
-
- outbox_text_box->setValue(outbox_text);
- outbox_title_box->setValue(outbox_title);
- outbox_placeholder_parent->setToolTip(outbox_tooltip);
-}
-
void LLSidepanelInventory::updateVerbs()
{
mInfoBtn->setEnabled(FALSE);
@@ -926,13 +658,6 @@ U32 LLSidepanelInventory::getSelectedCount()
{
selection_list = mInventoryPanelInbox->getRootFolder()->getSelectionList();
- count += selection_list.size();
- }
-
- if ((count == 0) && mOutboxEnabled && (mInventoryPanelOutbox != NULL))
- {
- selection_list = mInventoryPanelOutbox->getRootFolder()->getSelectionList();
-
count += selection_list.size();
}
@@ -957,7 +682,7 @@ BOOL LLSidepanelInventory::isMainInventoryPanelActive() const
return mInventoryPanel->getVisible();
}
-void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox, bool clearOutbox)
+void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
{
if (clearMain)
{
@@ -974,15 +699,10 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox, bool
mInventoryPanelInbox->clearSelection();
}
- if (clearOutbox && mOutboxEnabled && (mInventoryPanelOutbox != NULL))
- {
- mInventoryPanelOutbox->clearSelection();
- }
-
updateVerbs();
}
-std::set<LLUUID> LLSidepanelInventory::getInboxOrOutboxSelectionList()
+std::set<LLUUID> LLSidepanelInventory::getInboxSelectionList()
{
std::set<LLUUID> inventory_selected_uuids;
@@ -991,10 +711,5 @@ std::set<LLUUID> LLSidepanelInventory::getInboxOrOutboxSelectionList()
inventory_selected_uuids = mInventoryPanelInbox->getRootFolder()->getSelectionList();
}
- if (inventory_selected_uuids.empty() && mOutboxEnabled && (mInventoryPanelOutbox != NULL))
- {
- inventory_selected_uuids = mInventoryPanelOutbox->getRootFolder()->getSelectionList();
- }
-
return inventory_selected_uuids;
}
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index 2c6f807013..a33607f50d 100644
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -31,7 +31,7 @@
class LLButton;
class LLFolderViewItem;
-class LLInboxOutboxAddedObserver;
+class LLInboxAddedObserver;
class LLInventoryCategoriesObserver;
class LLInventoryItem;
class LLInventoryPanel;
@@ -47,25 +47,23 @@ public:
virtual ~LLSidepanelInventory();
private:
- void updateInboxOutbox();
+ void updateInbox();
public:
- void observeInboxOutboxCreation();
+ void observeInboxCreation();
void observeInboxModifications(const LLUUID& inboxID);
- void observeOutboxModifications(const LLUUID& outboxID);
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
LLInventoryPanel* getActivePanel(); // Returns an active inventory panel, if any.
LLInventoryPanel* getInboxPanel() const { return mInventoryPanelInbox; }
- LLInventoryPanel* getOutboxPanel() const { return mInventoryPanelOutbox; }
LLPanelMainInventory* getMainInventoryPanel() const { return mPanelMainInventory; }
BOOL isMainInventoryPanelActive() const;
- void clearSelections(bool clearMain, bool clearInbox, bool clearOutbox);
- std::set<LLUUID> getInboxOrOutboxSelectionList();
+ void clearSelections(bool clearMain, bool clearInbox);
+ std::set<LLUUID> getInboxSelectionList();
void showItemInfoPanel();
void showTaskInfoPanel();
@@ -75,18 +73,13 @@ public:
bool canShare();
void onToggleInboxBtn();
- void onToggleOutboxBtn();
void enableInbox(bool enabled);
- void enableOutbox(bool enabled);
void openInbox();
- void openOutbox();
bool isInboxEnabled() const { return mInboxEnabled; }
- bool isOutboxEnabled() const { return mOutboxEnabled; }
- void updateOutboxUserStatus();
void updateVerbs();
protected:
@@ -100,9 +93,6 @@ protected:
bool canWearSelected(); // check whether selected items can be worn
void onInboxChanged(const LLUUID& inbox_id);
- void onOutboxChanged(const LLUUID& outbox_id);
-
- bool manageInboxOutboxPanels(LLButton * pressedButton, LLLayoutPanel * pressedPanel, LLButton * otherButton, LLLayoutPanel * otherPanel);
//
// UI Elements
@@ -110,7 +100,6 @@ protected:
private:
LLPanel* mInventoryPanel; // Main inventory view
LLInventoryPanel* mInventoryPanelInbox;
- LLInventoryPanel* mInventoryPanelOutbox;
LLSidepanelItemInfo* mItemPanel; // Individual item view
LLSidepanelTaskInfo* mTaskPanel; // Individual in-world object view
LLPanelMainInventory* mPanelMainInventory;
@@ -135,10 +124,9 @@ private:
LLButton* mShopBtn;
bool mInboxEnabled;
- bool mOutboxEnabled;
- LLInventoryCategoriesObserver* mCategoriesObserver;
- LLInboxOutboxAddedObserver* mInboxOutboxAddedObserver;
+ LLInventoryCategoriesObserver* mCategoriesObserver;
+ LLInboxAddedObserver* mInboxAddedObserver;
};
#endif //LL_LLSIDEPANELINVENTORY_H
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 3e16ccf3da..5d196a465f 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -28,6 +28,10 @@
#include "llspatialpartition.h"
+#include "llappviewer.h"
+#include "lltexturecache.h"
+#include "lltexturefetch.h"
+#include "llimageworker.h"
#include "llviewerwindow.h"
#include "llviewerobjectlist.h"
#include "llvovolume.h"
@@ -260,7 +264,7 @@ static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");
void LLSpatialGroup::buildOcclusion()
{
- if (mOcclusionVerts.isNull())
+ //if (mOcclusionVerts.isNull())
{
mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX,
LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling.
@@ -722,7 +726,9 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
if (vertex_count > 0 && index_count > 0)
{ //create vertex buffer containing volume geometry for this node
group->mBuilt = 1.f;
- if (group->mVertexBuffer.isNull() || (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
+ if (group->mVertexBuffer.isNull() ||
+ !group->mVertexBuffer->isWriteable() ||
+ (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
{
group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true);
@@ -1181,6 +1187,8 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode)
LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mState(0),
+ mGeometryBytes(0),
+ mSurfaceArea(0.f),
mBuilt(0.f),
mOctreeNode(node),
mSpatialPartition(part),
@@ -1221,6 +1229,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
{
mOcclusionQuery[i] = 0;
+ mOcclusionIssued[i] = 0;
mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0;
mVisible[i] = 0;
}
@@ -1405,6 +1414,17 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)
}
}
+ //clean up avatar attachment stats
+ LLSpatialBridge* bridge = mSpatialPartition->asBridge();
+ if (bridge)
+ {
+ if (bridge->mAvatar.notNull())
+ {
+ bridge->mAvatar->mAttachmentGeometryBytes -= mGeometryBytes;
+ bridge->mAvatar->mAttachmentSurfaceArea -= mSurfaceArea;
+ }
+ }
+
clearDrawMap();
mVertexBuffer = NULL;
mBufferMap.clear();
@@ -1543,6 +1563,8 @@ BOOL LLSpatialGroup::rebound()
}
static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Wait");
+
void LLSpatialGroup::checkOcclusion()
{
if (LLPipeline::sUseOcclusion > 1)
@@ -1560,6 +1582,22 @@ void LLSpatialGroup::checkOcclusion()
if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+
+ if (mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
+ { //query was issued last frame, wait until it's available
+ S32 max_loop = 1024;
+ LLFastTimer t(FTM_OCCLUSION_WAIT);
+ while (!available && max_loop-- > 0)
+ {
+ F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+ //do some usefu work while we wait
+ LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
+ LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
+ LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
+
+ glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ }
+ }
}
else
{
@@ -1679,6 +1717,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
{
LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);
+ //store which frame this query was issued on
+ mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount;
+
{
LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY);
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
@@ -1739,7 +1780,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
//==============================================
LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage)
-: mRenderByGroup(render_by_group)
+: mRenderByGroup(render_by_group), mBridge(NULL)
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
mOcclusionEnabled = TRUE;
@@ -3749,11 +3790,7 @@ void renderRaycast(LLDrawable* drawablep)
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
- if (!face.mOctree)
- {
- ((LLVolumeFace*) &face)->createOctree();
- }
-
+
gGL.pushMatrix();
gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
@@ -3776,9 +3813,6 @@ void renderRaycast(LLDrawable* drawablep)
LLVector4a dir;
dir.setSub(enda, starta);
- F32 t = 1.f;
-
- LLRenderOctreeRaycast render(starta, dir, &t);
gGL.flush();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -3790,8 +3824,21 @@ void renderRaycast(LLDrawable* drawablep)
gGL.syncMatrices();
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
}
-
- render.traverse(face.mOctree);
+
+ if (!volume->isUnique())
+ {
+ F32 t = 1.f;
+
+ if (!face.mOctree)
+ {
+ ((LLVolumeFace*) &face)->createOctree();
+ }
+
+ LLRenderOctreeRaycast render(starta, dir, &t);
+
+ render.traverse(face.mOctree);
+ }
+
gGL.popMatrix();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index f0c8a372ee..6c14ecf452 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -396,6 +396,8 @@ protected:
U32 mState;
U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS];
+ U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS];
+
S32 mLODHash;
static S32 sLODSeed;
@@ -403,6 +405,9 @@ public:
bridge_list_t mBridgeList;
buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers
+ U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node
+ F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node
+
F32 mBuilt;
OctreeNode* mOctreeNode;
LLSpatialPartition* mSpatialPartition;
@@ -472,8 +477,8 @@ public:
BOOL isVisible(const LLVector3& v);
bool isHUDPartition() ;
- virtual LLSpatialBridge* asBridge() { return NULL; }
- virtual BOOL isBridge() { return asBridge() != NULL; }
+ LLSpatialBridge* asBridge() { return mBridge; }
+ BOOL isBridge() { return asBridge() != NULL; }
void renderPhysicsShapes();
void renderDebug();
@@ -485,6 +490,9 @@ public:
public:
LLSpatialGroup::OctreeNode* mOctree;
+ LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this
+ // use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe
+ // to call asBridge() from the destructor
BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed
BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane
U32 mBufferUsage;
@@ -509,8 +517,9 @@ public:
LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask);
- virtual BOOL isSpatialBridge() const { return TRUE; }
+ void destroyTree();
+ virtual BOOL isSpatialBridge() const { return TRUE; }
virtual void updateSpatialExtents();
virtual void updateBinRadius();
virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
@@ -521,11 +530,12 @@ public:
virtual void shiftPos(const LLVector4a& vec);
virtual void cleanupReferences();
virtual LLSpatialPartition* asPartition() { return this; }
- virtual LLSpatialBridge* asBridge() { return this; }
-
+
virtual LLCamera transformCamera(LLCamera& camera);
LLDrawable* mDrawable;
+ LLPointer<LLVOAvatar> mAvatar;
+
};
class LLCullResult
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 36d6ff3ef2..3923b4510a 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -804,9 +804,8 @@ bool idle_startup()
#ifdef _WIN32
MSG msg;
while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) )
- {
- display_startup();
- }
+ { }
+ display_startup();
#endif
timeout.reset();
return FALSE;
@@ -2026,7 +2025,7 @@ bool idle_startup()
const F32 wearables_time = wearables_timer.getElapsedTimeF32();
const F32 MAX_WEARABLES_TIME = 10.f;
- if (!gAgent.isGenderChosen())
+ if (!gAgent.isGenderChosen() && isAgentAvatarValid())
{
// No point in waiting for clothing, we don't even
// know what gender we are. Pop a dialog to ask and
@@ -2541,6 +2540,12 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
gender = SEX_FEMALE;
}
+ if (!isAgentAvatarValid())
+ {
+ llwarns << "Trying to load an initial outfit for an invalid agent avatar" << llendl;
+ return;
+ }
+
gAgentAvatarp->setSex(gender);
// try to find the outfit - if not there, create some default
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 3aa6a3b7e5..0cb6c85012 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -159,6 +159,7 @@ void LLSysWellWindow::setVisible(BOOL visible)
LLTransientDockableFloater::setVisible(visible);
// update notification channel state
+ initChannel(); // make sure the channel still exists
if(mChannel)
{
mChannel->updateShowToastsState();
@@ -598,6 +599,13 @@ LLIMWellWindow* LLIMWellWindow::getInstance(const LLSD& key /*= LLSD()*/)
return LLFloaterReg::getTypedInstance<LLIMWellWindow>("im_well_window", key);
}
+
+// static
+LLIMWellWindow* LLIMWellWindow::findInstance(const LLSD& key /*= LLSD()*/)
+{
+ return LLFloaterReg::findTypedInstance<LLIMWellWindow>("im_well_window", key);
+}
+
BOOL LLIMWellWindow::postBuild()
{
BOOL rv = LLSysWellWindow::postBuild();
@@ -751,7 +759,10 @@ void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id)
{
if (mMessageList->removeItemByValue(notification_id))
{
- mSysWellChiclet->updateWidget(isWindowEmpty());
+ if (mSysWellChiclet)
+ {
+ mSysWellChiclet->updateWidget(isWindowEmpty());
+ }
}
else
{
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 52e5370505..272e9cfcb1 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -153,6 +153,7 @@ public:
~LLIMWellWindow();
static LLIMWellWindow* getInstance(const LLSD& key = LLSD());
+ static LLIMWellWindow* findInstance(const LLSD& key = LLSD());
static void initClass() { getInstance(); }
/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
index 85dadb213c..4f43547dae 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/newview/lltexlayer.h
@@ -261,6 +261,8 @@ private:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLTexLayerSetBuffer : public LLViewerDynamicTexture
{
+ LOG_CLASS(LLTexLayerSetBuffer);
+
public:
LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
virtual ~LLTexLayerSetBuffer();
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index e7a176f4f9..8632890bbb 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -760,7 +760,7 @@ LLTextureCache::~LLTextureCache()
//////////////////////////////////////////////////////////////////////////////
//virtual
-S32 LLTextureCache::update(U32 max_time_ms)
+S32 LLTextureCache::update(F32 max_time_ms)
{
static LLFrameTimer timer ;
static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds.
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 64e3a2658c..dd0cc9b4bd 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -101,7 +101,7 @@ public:
LLTextureCache(bool threaded);
~LLTextureCache();
- /*virtual*/ S32 update(U32 max_time_ms);
+ /*virtual*/ S32 update(F32 max_time_ms);
void purgeCache(ELLPath location);
void setReadOnly(BOOL read_only) ;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 56dfb61c4f..f18aa8b4e6 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -2204,7 +2204,7 @@ void LLTextureFetch::commonUpdate()
// MAIN THREAD
//virtual
-S32 LLTextureFetch::update(U32 max_time_ms)
+S32 LLTextureFetch::update(F32 max_time_ms)
{
static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS");
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index d101da1f4b..35df7d816f 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -55,7 +55,7 @@ public:
class TFRequest;
- /*virtual*/ S32 update(U32 max_time_ms);
+ /*virtual*/ S32 update(F32 max_time_ms);
void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down.
void shutDownImageDecodeThread() ; //called in the main thread after the ImageDecodeThread shuts down.
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 6910b8eced..8c32dfcb4d 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -282,6 +282,8 @@ void LLCategoryDropDescendentsObserver::done()
}
*/
+S32 LLToolDragAndDrop::sOperationId = 0;
+
LLToolDragAndDrop::DragAndDropEntry::DragAndDropEntry(dragOrDrop3dImpl f_none,
dragOrDrop3dImpl f_self,
dragOrDrop3dImpl f_avatar,
@@ -626,6 +628,8 @@ BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, MASK mask)
void LLToolDragAndDrop::handleDeselect()
{
mToolTipMsg.clear();
+
+ LLToolTipMgr::instance().blockToolTips();
}
// protected
@@ -642,6 +646,12 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
mToolTipMsg.clear();
+ // Increment the operation id for every drop
+ if (drop)
+ {
+ sOperationId++;
+ }
+
if (top_view)
{
handled = TRUE;
@@ -767,6 +777,21 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
if (!handled)
{
+ // Disallow drag and drop to 3D from the outbox
+ const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+ if (outbox_id.notNull())
+ {
+ for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++)
+ {
+ if (gInventory.isObjectDescendentOf(mCargoIDs[item_index], outbox_id))
+ {
+ *acceptance = ACCEPT_NO;
+ mToolTipMsg = LLTrans::getString("TooltipOutboxDragToWorld");
+ return;
+ }
+ }
+ }
+
dragOrDrop3D( x, y, mask, drop, acceptance );
}
}
@@ -865,7 +890,7 @@ void LLToolDragAndDrop::pick(const LLPickInfo& pick_info)
(U32)mLastAccept,
(U32)callMemberFunction(*this,
LLDragAndDropDictionary::instance().get(dad_type, target))
- (hit_obj, hit_face, pick_info.mKeyMask, FALSE));
+ (hit_obj, hit_face, pick_info.mKeyMask, FALSE));
}
if (mDrop && ((U32)mLastAccept >= ACCEPT_YES_COPY_SINGLE))
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 92f007a251..188d36cd1b 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -86,6 +86,9 @@ public:
EAcceptance getLastAccept() { return mLastAccept; }
boost::signals2::connection setEndDragCallback( const enddrag_signal_t::slot_type& cb ) { return mEndDragSignal.connect(cb); }
+
+ uuid_vec_t::size_type getCargoIDsCount() const { return mCargoIDs.size(); }
+ static S32 getOperationId() { return sOperationId; }
protected:
enum EDropTarget
@@ -125,6 +128,8 @@ protected:
LLUUID mSourceID;
LLUUID mObjectID;
+ static S32 sOperationId;
+
LLVector3d mLastCameraPos;
LLVector3d mLastHitPos;
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index 7eb54271f4..c1cc9c7bc4 100755
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -95,6 +95,12 @@ bool LLGoogleTranslationHandler::parseResponse(
return parseTranslation(root, translation, detected_lang);
}
+// virtual
+bool LLGoogleTranslationHandler::isConfigured() const
+{
+ return !getAPIKey().empty();
+}
+
// static
void LLGoogleTranslationHandler::parseErrorResponse(
const Json::Value& root,
@@ -218,6 +224,12 @@ bool LLBingTranslationHandler::parseResponse(
return true;
}
+// virtual
+bool LLBingTranslationHandler::isConfigured() const
+{
+ return !getAPIKey().empty();
+}
+
// static
std::string LLBingTranslationHandler::getAPIKey()
{
@@ -332,6 +344,12 @@ std::string LLTranslate::getTranslateLanguage()
}
// static
+bool LLTranslate::isTranslationConfigured()
+{
+ return getPreferredHandler().isConfigured();
+}
+
+// static
const LLTranslationAPIHandler& LLTranslate::getPreferredHandler()
{
EService service = SERVICE_BING;
diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h
index c2330daa81..424bc14587 100755
--- a/indra/newview/lltranslate.h
+++ b/indra/newview/lltranslate.h
@@ -89,6 +89,11 @@ public:
std::string& detected_lang,
std::string& err_msg) const = 0;
+ /**
+ * @return if the handler is configured to function properly
+ */
+ virtual bool isConfigured() const = 0;
+
virtual ~LLTranslationAPIHandler() {}
protected:
@@ -115,6 +120,7 @@ public:
std::string& translation,
std::string& detected_lang,
std::string& err_msg) const;
+ /*virtual*/ bool isConfigured() const;
private:
static void parseErrorResponse(
@@ -148,6 +154,7 @@ public:
std::string& translation,
std::string& detected_lang,
std::string& err_msg) const;
+ /*virtual*/ bool isConfigured() const;
private:
static std::string getAPIKey();
};
@@ -275,8 +282,17 @@ public :
* @param key Key to verify.
*/
static void verifyKey(KeyVerificationReceiverPtr& receiver, const std::string& key);
+
+ /**
+ * @return translation target language
+ */
static std::string getTranslateLanguage();
+ /**
+ * @return true if translation is configured properly.
+ */
+ static bool isTranslationConfigured();
+
private:
static const LLTranslationAPIHandler& getPreferredHandler();
static const LLTranslationAPIHandler& getHandler(EService service);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 8406f639df..bb870f7651 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -83,6 +83,7 @@
#include "llfloaternotificationsconsole.h"
#include "llfloaterobjectweights.h"
#include "llfloateropenobject.h"
+#include "llfloateroutbox.h"
#include "llfloaterpay.h"
#include "llfloaterperms.h"
#include "llfloaterpostprocess.h"
@@ -238,6 +239,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("object_weights", "floater_object_weights.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterObjectWeights>);
LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
+ LLFloaterReg::add("outbox", "floater_merchant_outbox.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutbox>);
LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>);
LLFloaterPayUtil::registerFloater();
@@ -294,9 +296,10 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterUIPreviewUtil::registerFloater();
LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload");
LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterImagePreview>, "upload");
- LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
LLFloaterReg::add("upload_model", "floater_model_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelPreview>, "upload");
LLFloaterReg::add("upload_model_wizard", "floater_model_wizard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelWizard>);
+ LLFloaterReg::add("upload_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptPreview>, "upload");
+ LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);
LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 42dabdec0d..046360e9e9 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -26,46 +26,48 @@
#include "llviewerprecompiledheaders.h"
+#include "llviewermedia.h"
+
#include "llagent.h"
#include "llagentcamera.h"
-#include "llviewermedia.h"
-#include "llviewermediafocus.h"
-#include "llmimetypes.h"
+#include "llappviewer.h"
+#include "llaudioengine.h" // for gAudiop
+#include "llcallbacklist.h"
+#include "lldir.h"
+#include "lldiriterator.h"
+#include "llevent.h" // LLSimpleListener
+#include "llfilepicker.h"
+#include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows.
+#include "llfocusmgr.h"
+#include "llkeyboard.h"
+#include "lllogininstance.h"
+#include "llmarketplacefunctions.h"
#include "llmediaentry.h"
+#include "llmimetypes.h"
+#include "llmutelist.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llpanelprofile.h"
+#include "llparcel.h"
+#include "llpluginclassmedia.h"
+#include "llplugincookiestore.h"
+#include "llurldispatcher.h"
+#include "lluuid.h"
#include "llversioninfo.h"
+#include "llviewermediafocus.h"
#include "llviewercontrol.h"
-#include "llviewertexture.h"
+#include "llviewernetwork.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llviewertexture.h"
#include "llviewertexturelist.h"
-#include "llvovolume.h"
-#include "llpluginclassmedia.h"
-#include "llplugincookiestore.h"
#include "llviewerwindow.h"
-#include "llfocusmgr.h"
-#include "llcallbacklist.h"
-#include "llparcel.h"
-#include "llaudioengine.h" // for gAudiop
-#include "llurldispatcher.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
-#include "llviewerregion.h"
+#include "llvovolume.h"
#include "llwebprofile.h"
#include "llwebsharing.h" // For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this!
-#include "llfilepicker.h"
-#include "llnotifications.h"
-#include "lldir.h"
-#include "lldiriterator.h"
-#include "llevent.h" // LLSimpleListener
-#include "llnotificationsutil.h"
-#include "lluuid.h"
-#include "llkeyboard.h"
-#include "llmutelist.h"
-#include "llpanelprofile.h"
-#include "llappviewer.h"
-#include "lllogininstance.h"
-//#include "llfirstuse.h"
-#include "llviewernetwork.h"
#include "llwindow.h"
#include "llvieweraudio.h"
@@ -1398,75 +1400,11 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom
}
-// This is defined in two files but I don't want to create a dependence between this and llsidepanelinventory
-// just to be able to temporarily disable the outbox.
-#define ENABLE_INVENTORY_DISPLAY_OUTBOX 0 // keep in sync with ENABLE_MERCHANT_OUTBOX_PANEL, ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
-
-class LLInventoryUserStatusResponder : public LLHTTPClient::Responder
-{
-public:
- LLInventoryUserStatusResponder()
- : LLCurl::Responder()
- {
- }
-
- void completed(U32 status, const std::string& reason, const LLSD& content)
- {
- if (isGoodStatus(status))
- {
- std::string merchantStatus = content[gAgent.getID().getString()].asString();
- llinfos << "Marketplace merchant status: " << merchantStatus << llendl;
-
- // Save the merchant status before turning on the display
- gSavedSettings.setString("InventoryMarketplaceUserStatus", merchantStatus);
-
- // Complete success
- gSavedSettings.setBOOL("InventoryDisplayInbox", true);
-
-#if ENABLE_INVENTORY_DISPLAY_OUTBOX
- gSavedSettings.setBOOL("InventoryDisplayOutbox", true);
-#endif
- }
- else if (status == 401)
- {
- // API is available for use but OpenID authorization failed
- gSavedSettings.setBOOL("InventoryDisplayInbox", true);
- }
- else
- {
- // API in unavailable
- llinfos << "Marketplace API is unavailable -- Inbox may be disabled, status = " << status << ", reason = " << reason << llendl;
- }
- }
-};
-
-
-void doOnetimeEarlyHTTPRequests()
-{
- std::string url = "https://marketplace.secondlife.com/";
-
- if (!LLGridManager::getInstance()->isInProductionGrid())
- {
- std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
- url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str());
-
- // TEMP for Jim's pdp
- //url = "http://pdp24.lindenlab.com:3000/";
- }
-
- url += "api/1/users/";
- url += gAgent.getID().getString();
- url += "/user_status";
-
- llinfos << "http get: " << url << llendl;
- LLHTTPClient::get(url, new LLInventoryUserStatusResponder(), LLViewerMedia::getHeaders());
-}
-
-
LLSD LLViewerMedia::getHeaders()
{
LLSD headers = LLSD::emptyMap();
headers["Accept"] = "*/*";
+ headers["Content-Type"] = "application/xml";
headers["Cookie"] = sOpenIDCookie;
headers["User-Agent"] = getCurrentUserAgent();
@@ -1521,9 +1459,6 @@ void LLViewerMedia::setOpenIDCookie()
LLHTTPClient::get(profile_url,
new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
headers);
-
- // FUI: No longer perform the user_status query
- //doOnetimeEarlyHTTPRequests();
}
}
@@ -1966,7 +1901,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
}
}
- LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << media_type << LL_ENDL;
+ LL_WARNS_ONCE("Plugin") << "plugin intialization failed for mime type: " << media_type << LL_ENDL;
LLSD args;
args["MIME_TYPE"] = media_type;
LLNotificationsUtil::add("NoPlugin", args);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 3a1b8d7623..99540ccce9 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -947,6 +947,10 @@ U32 info_display_from_string(std::string info_display)
{
return LLPipeline::RENDER_DEBUG_COMPOSITION;
}
+ else if ("attachment bytes" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES;
+ }
else if ("glow" == info_display)
{
return LLPipeline::RENDER_DEBUG_GLOW;
@@ -2203,6 +2207,30 @@ class LLAdvancedEnableToggleHackedGodmode : public view_listener_t
//// Advanced menu
////-------------------------------------------------------------------
+
+//////////////////
+// DEVELOP MENU //
+//////////////////
+
+class LLDevelopCheckLoggingLevel : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 level = userdata.asInteger();
+ return (static_cast<LLError::ELevel>(level) == LLError::getDefaultLevel());
+ }
+};
+
+class LLDevelopSetLoggingLevel : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 level = userdata.asInteger();
+ LLError::setDefaultLevel(static_cast<LLError::ELevel>(level));
+ return true;
+ }
+};
+
//////////////////
// ADMIN MENU //
//////////////////
@@ -2762,8 +2790,31 @@ bool enable_object_mute()
else
{
// Just a regular object
- return LLSelectMgr::getInstance()->getSelection()->
- contains( object, SELECT_ALL_TES );
+ return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) &&
+ !LLMuteList::getInstance()->isMuted(object->getID());
+ }
+}
+
+bool enable_object_unmute()
+{
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object) return false;
+
+ LLVOAvatar* avatar = find_avatar_from_object(object);
+ if (avatar)
+ {
+ // It's an avatar
+ LLNameValue *lastname = avatar->getNVPair("LastName");
+ bool is_linden =
+ lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden");
+ bool is_self = avatar->isSelf();
+ return !is_linden && !is_self;
+ }
+ else
+ {
+ // Just a regular object
+ return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) &&
+ LLMuteList::getInstance()->isMuted(object->getID());;
}
}
@@ -8195,6 +8246,9 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedRequestAdminStatus(), "Advanced.RequestAdminStatus");
view_listener_t::addMenu(new LLAdvancedLeaveAdminStatus(), "Advanced.LeaveAdminStatus");
+ // Develop >Set logging level
+ view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");
+ view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel");
// Admin >Object
view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
@@ -8281,6 +8335,7 @@ void initialize_menus()
enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute));
enable.add("Object.EnableMute", boost::bind(&enable_object_mute));
+ enable.add("Object.EnableUnmute", boost::bind(&enable_object_unmute));
enable.add("Object.EnableBuy", boost::bind(&enable_buy_object));
commit.add("Object.ZoomIn", boost::bind(&handle_look_at_selection, "zoom"));
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index b8772971aa..37fb77a10a 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -5520,11 +5520,12 @@ void LLViewerObject::dirtyMesh()
{
if (mDrawable)
{
- LLSpatialGroup* group = mDrawable->getSpatialGroup();
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
+ /*LLSpatialGroup* group = mDrawable->getSpatialGroup();
if (group)
{
group->dirtyMesh();
- }
+ }*/
}
}
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index f738b84bb9..6c8a827ba3 100644
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -57,6 +57,8 @@
#include "lldeleteutils.h"
#include "imageids.h"
#include "indra_constants.h"
+#include "llinitparam.h"
+
//#include "linden_common.h"
//#include "llpreprocessor.h"
#include "llallocator.h"
@@ -124,7 +126,5 @@
// Library includes from llmessage project
#include "llcachename.h"
-// Library includes from llxuixml
-#include "llinitparam.h"
#endif
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index ed943964f9..e3cb985ddb 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1493,6 +1493,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("AvatarPickerSearch");
capabilityNames.append("ChatSessionRequest");
capabilityNames.append("CopyInventoryFromNotecard");
+ capabilityNames.append("CreateInventoryCategory");
capabilityNames.append("DispatchRegionInfo");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index bddc07b395..5de363e03c 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -1103,11 +1103,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader";
gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true;
gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true;
gDeferredSkinnedAlphaProgram.mShaderFiles.clear();
gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
@@ -1235,6 +1236,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaProgram.mFeatures.hasGamma = true;
gDeferredAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAlphaProgram.mFeatures.hasLighting = true;
+ gDeferredAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
{
@@ -1398,6 +1400,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
+ gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
gDeferredAvatarAlphaProgram.mShaderFiles.clear();
gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaV.glsl", GL_VERTEX_SHADER_ARB));
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index f4bbc2b067..61236edc86 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -417,11 +417,24 @@ const S32 min_non_tex_system_mem = (128<<20); // 128 MB
F32 texmem_lower_bound_scale = 0.85f;
F32 texmem_middle_bound_scale = 0.925f;
+static LLFastTimer::DeclareTimer FTM_TEXTURE_MEMORY_CHECK("Memory Check");
+
//static
bool LLViewerTexture::isMemoryForTextureLow()
{
- const static S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB
- const static S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB
+ const F32 WAIT_TIME = 1.0f ; //second
+ static LLFrameTimer timer ;
+
+ if(timer.getElapsedTimeF32() < WAIT_TIME) //call this once per second.
+ {
+ return false;
+ }
+ timer.reset() ;
+
+ LLFastTimer t(FTM_TEXTURE_MEMORY_CHECK);
+
+ const S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB
+ const S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB
bool low_mem = false ;
if (gGLManager.mHasATIMemInfo)
@@ -433,6 +446,15 @@ bool LLViewerTexture::isMemoryForTextureLow()
{
low_mem = true ;
}
+
+ if(!low_mem) //check main memory, only works for windows.
+ {
+ LLMemory::updateMemoryInfo() ;
+ if(LLMemory::getAvailableMemKB() / 1024 < MIN_FREE_MAIN_MEMORy)
+ {
+ low_mem = true ;
+ }
+ }
}
#if 0 //ignore nVidia cards
else if (gGLManager.mHasNVXMemInfo)
@@ -445,20 +467,14 @@ bool LLViewerTexture::isMemoryForTextureLow()
low_mem = true ;
}
}
-#endif
-
- if(!low_mem) //check main memory, only works for windows.
- {
- LLMemory::updateMemoryInfo() ;
- if(LLMemory::getAvailableMemKB() / 1024 < MIN_FREE_MAIN_MEMORy)
- {
- low_mem = true ;
- }
- }
+#endif
return low_mem ;
}
+static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_MEDIA("Media");
+static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_TEST("Test");
+
//static
void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity)
{
@@ -467,9 +483,14 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
if (tester)
{
+ LLFastTimer t(FTM_TEXTURE_UPDATE_TEST);
tester->update() ;
}
- LLViewerMediaTexture::updateClass() ;
+
+ {
+ LLFastTimer t(FTM_TEXTURE_UPDATE_MEDIA);
+ LLViewerMediaTexture::updateClass() ;
+ }
sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes
sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes
@@ -3142,8 +3163,13 @@ void LLViewerLODTexture::processTextureStats()
S32 current_discard = getDiscardLevel();
if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLViewerTexture::BOOST_SCULPTED && current_discard >= 0)
{
+ if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage)
+ {
+ //needs to release texture memory urgently
+ scaleDown() ;
+ }
// Limit the amount of GL memory bound each frame
- if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale &&
+ else if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale &&
(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
{
scaleDown() ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index cddf7dcfea..089f45ca89 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -534,6 +534,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
S32 count = mImageList.erase(image) ;
if(count != 1)
{
+ llinfos << image->getID() << llendl ;
llerrs << "Error happens when remove image from mImageList: " << count << llendl ;
}
@@ -919,6 +920,8 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
image_list.push_back(imagep);
imagep->setInImageList(FALSE) ;
}
+
+ llassert_always(image_list.size() == mImageList.size()) ;
mImageList.clear();
for (std::vector<LLPointer<LLViewerFetchedTexture> >::iterator iter = image_list.begin();
iter != image_list.end(); ++iter)
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 31dfa1923c..8a713ae22c 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -130,6 +130,7 @@
#include "llmorphview.h"
#include "llmoveview.h"
#include "llnavigationbar.h"
+#include "llpaneltopinfobar.h"
#include "llpopupview.h"
#include "llpreviewtexture.h"
#include "llprogressview.h"
@@ -612,7 +613,9 @@ public:
addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,
LLMeshRepository::sHTTPRetryCount));
-
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing));
ypos += y_inc;
addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f)));
@@ -1205,7 +1208,8 @@ void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask
mWindow->showCursorFromMouseMove();
- if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
+ if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME
+ && !gDisconnected)
{
gAgent.clearAFK();
}
@@ -1956,34 +1960,43 @@ void LLViewerWindow::shutdownViews()
// clean up warning logger
LLError::removeRecorder(RecordToChatConsole::getInstance());
+ llinfos << "Warning logger is cleaned." << llendl ;
+
delete mDebugText;
mDebugText = NULL;
+ llinfos << "DebugText deleted." << llendl ;
+
// Cleanup global views
if (gMorphView)
{
gMorphView->setVisible(FALSE);
}
-
+ llinfos << "Global views cleaned." << llendl ;
+
// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
// will crump with LL_ERRS.
LLModalDialog::shutdownModals();
-
+ llinfos << "LLModalDialog shut down." << llendl;
+
// destroy the nav bar, not currently part of gViewerWindow
// *TODO: Make LLNavigationBar part of gViewerWindow
if (LLNavigationBar::instanceExists())
{
delete LLNavigationBar::getInstance();
}
-
+ llinfos << "LLNavigationBar destroyed." << llendl ;
+
// destroy menus after instantiating navbar above, as it needs
// access to gMenuHolder
cleanup_menus();
-
+ llinfos << "menus destroyed." << llendl ;
+
// Delete all child views.
delete mRootView;
mRootView = NULL;
-
+ llinfos << "RootView deleted." << llendl ;
+
// Automatically deleted as children of mRootView. Fix the globals.
gStatusBar = NULL;
gIMMgr = NULL;
@@ -5001,8 +5014,8 @@ void LLViewerWindow::setUIVisibility(bool visible)
gToolBarView->setToolBarsVisible(visible);
}
- mRootView->getChildView("topinfo_bar_container")->setVisible(visible);
- mRootView->getChildView("nav_bar_container")->setVisible(visible);
+ LLNavigationBar::getInstance()->setVisible(visible ? gSavedSettings.getBOOL("ShowNavbarNavigationPanel") : FALSE);
+ LLPanelTopInfoBar::getInstance()->setVisible(visible? gSavedSettings.getBOOL("ShowMiniLocationPanel") : FALSE);
mRootView->getChildView("status_bar_container")->setVisible(visible);
}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 4767ba2bed..bc7f5a9744 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -651,6 +651,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
LLViewerObject(id, pcode, regionp),
mIsDummy(FALSE),
mSpecialRenderMode(0),
+ mAttachmentGeometryBytes(0),
+ mAttachmentSurfaceArea(0.f),
mTurning(FALSE),
mPelvisToFoot(0.f),
mLastSkeletonSerialNum( 0 ),
@@ -3363,6 +3365,16 @@ void LLVOAvatar::slamPosition()
mRoot.updateWorldMatrixChildren();
}
+bool LLVOAvatar::isVisuallyMuted()
+{
+ static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");
+ static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit");
+
+ return LLMuteList::getInstance()->isMuted(getID()) ||
+ (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||
+ (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
+}
+
//------------------------------------------------------------------------
// updateCharacter()
// called on both your avatar and other avatars
@@ -3429,8 +3441,9 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
size.setSub(ext[1],ext[0]);
F32 mag = size.getLength3().getF32()*0.5f;
+
F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f);
- if (LLMuteList::getInstance()->isMuted(getID()))
+ if (isVisuallyMuted())
{ // muted avatars update at 16 hz
mUpdatePeriod = 16;
}
@@ -5414,18 +5427,6 @@ BOOL LLVOAvatar::loadAvatar()
}
}
- // Uncomment to enable avatar_lad.xml debugging.
- std::ofstream file;
- file.open("avatar_lad.log");
- for( LLViewerVisualParam* param = (LLViewerVisualParam*) getFirstVisualParam();
- param;
- param = (LLViewerVisualParam*) getNextVisualParam() )
- {
- param->getInfo()->toStream(file);
- file << std::endl;
- }
-
- file.close();
return TRUE;
}
@@ -8345,6 +8346,11 @@ void LLVOAvatar::idleUpdateRenderCost()
static std::set<LLUUID> all_textures;
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES))
+ { //set debug text to attachment geometry bytes here so render cost will override
+ setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea));
+ }
+
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME))
{
return;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 59796370ae..dd0317f555 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -78,6 +78,8 @@ class LLVOAvatar :
public LLCharacter,
public boost::signals2::trackable
{
+ LOG_CLASS(LLVOAvatar);
+
public:
friend class LLVOAvatarSelf;
protected:
@@ -380,6 +382,8 @@ private:
public:
U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);
+ bool isVisuallyMuted();
+
U32 renderRigid();
U32 renderSkinned(EAvatarRenderPass pass);
F32 getLastSkinTime() { return mLastSkinTime; }
@@ -391,6 +395,9 @@ public:
static void restoreGL();
BOOL mIsDummy; // for special views
S32 mSpecialRenderMode; // special lighting
+ U32 mAttachmentGeometryBytes; //number of bytes in attached geometry
+ F32 mAttachmentSurfaceArea; //estimated surface area of attachments
+
private:
bool shouldAlphaMask();
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 581912f844..f1df67494f 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1574,7 +1574,7 @@ void LLVOAvatarSelf::invalidateAll()
{
invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, TRUE);
}
- mDebugSelfLoadTimer.reset();
+ //mDebugSelfLoadTimer.reset();
}
//-----------------------------------------------------------------------------
@@ -1896,11 +1896,13 @@ BOOL LLVOAvatarSelf::getIsCloud()
gAgentWearables.getWearableCount(LLWearableType::WT_EYES) == 0 ||
gAgentWearables.getWearableCount(LLWearableType::WT_SKIN) == 0)
{
+ lldebugs << "No body parts" << llendl;
return TRUE;
}
if (!isTextureDefined(TEX_HAIR, 0))
{
+ lldebugs << "No hair texture" << llendl;
return TRUE;
}
@@ -1909,12 +1911,14 @@ BOOL LLVOAvatarSelf::getIsCloud()
if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet) &&
(!isTextureDefined(TEX_LOWER_BAKED, 0)))
{
+ lldebugs << "Lower textures not baked" << llendl;
return TRUE;
}
if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_UPPER].mTexLayerSet) &&
(!isTextureDefined(TEX_UPPER_BAKED, 0)))
{
+ lldebugs << "Upper textures not baked" << llendl;
return TRUE;
}
@@ -1931,10 +1935,12 @@ BOOL LLVOAvatarSelf::getIsCloud()
const LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 );
if (!baked_img || !baked_img->hasGLTexture())
{
+ lldebugs << "Texture at index " << i << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << llendl;
return TRUE;
}
}
+ lldebugs << "Avatar de-clouded" << llendl;
}
return FALSE;
}
@@ -2258,6 +2264,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
}
}
+// FIXME: This is never called. Something may be broken.
void LLVOAvatarSelf::outputRezDiagnostics() const
{
if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
@@ -2315,6 +2322,18 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
}
}
+void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const
+{
+ LL_DEBUGS("Avatar Rez")
+ << llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32())
+ << llendl;
+}
+
+void LLVOAvatarSelf::reportAvatarRezTime() const
+{
+ // TODO: report mDebugSelfLoadTimer.getElapsedTimeF32() somehow.
+}
+
//-----------------------------------------------------------------------------
// setCachedBakedTexture()
// A baked texture id was received from a cache query, make it active
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 74ff47a3e4..54dbe81993 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -41,6 +41,7 @@ struct LocalTextureData;
class LLVOAvatarSelf :
public LLVOAvatar
{
+ LOG_CLASS(LLVOAvatarSelf);
/********************************************************************************
** **
@@ -358,6 +359,8 @@ public:
void debugWearablesLoaded() { mDebugTimeWearablesLoaded = mDebugSelfLoadTimer.getElapsedTimeF32(); }
void debugAvatarVisible() { mDebugTimeAvatarVisible = mDebugSelfLoadTimer.getElapsedTimeF32(); }
void outputRezDiagnostics() const;
+ void outputRezTiming(const std::string& msg) const;
+ void reportAvatarRezTime() const;
void debugBakedTextureUpload(LLVOAvatarDefines::EBakedTextureIndex index, BOOL finished);
static void debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index df1d3f2955..820d1d73e1 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -27,8 +27,6 @@
#include "llviewerprecompiledheaders.h"
#include "llvoicevivox.h"
-#include <boost/tokenizer.hpp>
-
#include "llsdutil.h"
// Linden library includes
@@ -47,6 +45,7 @@
#include "llbase64.h"
#include "llviewercontrol.h"
#include "llappviewer.h" // for gDisconnected, gDisableVoice
+#include "llprocess.h"
// Viewer includes
#include "llmutelist.h" // to check for muted avatars
@@ -242,59 +241,21 @@ void LLVivoxVoiceClientCapResponder::result(const LLSD& content)
}
}
-
-
-#if LL_WINDOWS
-static HANDLE sGatewayHandle = 0;
+static LLProcessPtr sGatewayPtr;
static bool isGatewayRunning()
{
- bool result = false;
- if(sGatewayHandle != 0)
- {
- DWORD waitresult = WaitForSingleObject(sGatewayHandle, 0);
- if(waitresult != WAIT_OBJECT_0)
- {
- result = true;
- }
- }
- return result;
-}
-static void killGateway()
-{
- if(sGatewayHandle != 0)
- {
- TerminateProcess(sGatewayHandle,0);
- }
-}
-
-#else // Mac and linux
-
-static pid_t sGatewayPID = 0;
-static bool isGatewayRunning()
-{
- bool result = false;
- if(sGatewayPID != 0)
- {
- // A kill with signal number 0 has no effect, just does error checking. It should return an error if the process no longer exists.
- if(kill(sGatewayPID, 0) == 0)
- {
- result = true;
- }
- }
- return result;
+ return sGatewayPtr && sGatewayPtr->isRunning();
}
static void killGateway()
{
- if(sGatewayPID != 0)
+ if (sGatewayPtr)
{
- kill(sGatewayPID, SIGTERM);
+ sGatewayPtr->kill();
}
}
-#endif
-
///////////////////////////////////////////////////////////////////////////////////////////////
LLVivoxVoiceClient::LLVivoxVoiceClient() :
@@ -790,7 +751,7 @@ void LLVivoxVoiceClient::stateMachine()
}
else if(!isGatewayRunning())
{
- if(true)
+ if (true) // production build, not test
{
// Launch the voice daemon
@@ -809,102 +770,33 @@ void LLVivoxVoiceClient::stateMachine()
#endif
// See if the vivox executable exists
llstat s;
- if(!LLFile::stat(exe_path, &s))
+ if (!LLFile::stat(exe_path, &s))
{
// vivox executable exists. Build the command line and launch the daemon.
+ LLProcess::Params params;
+ params.executable = exe_path;
// SLIM SDK: these arguments are no longer necessary.
// std::string args = " -p tcp -h -c";
- std::string args;
- std::string cmd;
std::string loglevel = gSavedSettings.getString("VivoxDebugLevel");
-
if(loglevel.empty())
{
loglevel = "-1"; // turn logging off completely
}
-
- args += " -ll ";
- args += loglevel;
-
- LL_DEBUGS("Voice") << "Args for SLVoice: " << args << LL_ENDL;
-
-#if LL_WINDOWS
- PROCESS_INFORMATION pinfo;
- STARTUPINFOA sinfo;
-
- memset(&sinfo, 0, sizeof(sinfo));
-
- std::string exe_dir = gDirUtilp->getAppRODataDir();
- cmd = "SLVoice.exe";
- cmd += args;
-
- // So retarded. Windows requires that the second parameter to CreateProcessA be writable (non-const) string...
- char *args2 = new char[args.size() + 1];
- strcpy(args2, args.c_str());
- if(!CreateProcessA(exe_path.c_str(), args2, NULL, NULL, FALSE, 0, NULL, exe_dir.c_str(), &sinfo, &pinfo))
- {
-// DWORD dwErr = GetLastError();
- }
- else
- {
- // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on
- // CloseHandle(pinfo.hProcess); // stops leaks - nothing else
- sGatewayHandle = pinfo.hProcess;
- CloseHandle(pinfo.hThread); // stops leaks - nothing else
- }
-
- delete[] args2;
-#else // LL_WINDOWS
- // This should be the same for mac and linux
- {
- std::vector<std::string> arglist;
- arglist.push_back(exe_path);
-
- // Split the argument string into separate strings for each argument
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep(" ");
- tokenizer tokens(args, sep);
- tokenizer::iterator token_iter;
- for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
- {
- arglist.push_back(*token_iter);
- }
-
- // create an argv vector for the child process
- char **fakeargv = new char*[arglist.size() + 1];
- int i;
- for(i=0; i < arglist.size(); i++)
- fakeargv[i] = const_cast<char*>(arglist[i].c_str());
+ params.args.add("-ll");
+ params.args.add(loglevel);
+ params.cwd = gDirUtilp->getAppRODataDir();
+ sGatewayPtr = LLProcess::create(params);
- fakeargv[i] = NULL;
-
- fflush(NULL); // flush all buffers before the child inherits them
- pid_t id = vfork();
- if(id == 0)
- {
- // child
- execv(exe_path.c_str(), fakeargv);
-
- // If we reach this point, the exec failed.
- // Use _exit() instead of exit() per the vfork man page.
- _exit(0);
- }
-
- // parent
- delete[] fakeargv;
- sGatewayPID = id;
- }
-#endif // LL_WINDOWS
mDaemonHost = LLHost(gSavedSettings.getString("VivoxVoiceHost").c_str(), gSavedSettings.getU32("VivoxVoicePort"));
- }
+ }
else
{
LL_INFOS("Voice") << exe_path << " not found." << LL_ENDL;
- }
+ }
}
else
- {
+ {
// SLIM SDK: port changed from 44124 to 44125.
// We can connect to a client gateway running on another host. This is useful for testing.
// To do this, launch the gateway on a nearby host like this:
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index c3a2e6a712..bf6158eeaf 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -65,7 +65,7 @@ public:
return;
}
- U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
+ volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
//assume tex coords 2 and 3 are present
U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 20f8674655..7492a06784 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4097,6 +4097,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
+ LLVOAvatar* pAvatarVO = NULL;
+
+ LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
+ if (bridge)
+ {
+ if (bridge->mAvatar.isNull())
+ {
+ LLViewerObject* vobj = bridge->mDrawable->getVObj();
+ if (vobj)
+ {
+ bridge->mAvatar = vobj->getAvatar();
+ }
+ }
+
+ pAvatarVO = bridge->mAvatar;
+ }
+
+ if (pAvatarVO)
+ {
+ pAvatarVO->mAttachmentGeometryBytes -= group->mGeometryBytes;
+ pAvatarVO->mAttachmentSurfaceArea -= group->mSurfaceArea;
+ }
+
+ group->mGeometryBytes = 0;
+ group->mSurfaceArea = 0;
+
group->clearDrawMap();
mFaceList.clear();
@@ -4133,12 +4159,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLVOVolume* vobj = drawablep->getVOVolume();
+ if (!vobj)
+ {
+ continue;
+ }
+
if (vobj->isMesh() &&
(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
{
continue;
}
+ LLVolume* volume = vobj->getVolume();
+ if (volume)
+ {
+ const LLVector3& scale = vobj->getScale();
+ group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
+ }
+
llassert_always(vobj);
vobj->updateTextureVirtualSize(true);
vobj->preRebuild();
@@ -4183,7 +4221,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//Determine if we've received skininfo that contains an
//alternate bind matrix - if it does then apply the translational component
//to the joints of the avatar.
- LLVOAvatar* pAvatarVO = vobj->getAvatar();
bool pelvisGotSet = false;
if ( pAvatarVO )
@@ -4253,13 +4290,16 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (type == LLDrawPool::POOL_ALPHA)
{
- if (te->getFullbright())
+ if (te->getColor().mV[3] > 0.f)
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+ if (te->getFullbright())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+ }
}
}
else if (te->getShiny())
@@ -4392,8 +4432,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
else
{
- drawablep->setState(LLDrawable::HAS_ALPHA);
- alpha_faces.push_back(facep);
+ if (te->getColor().mV[3] > 0.f)
+ {
+ drawablep->setState(LLDrawable::HAS_ALPHA);
+ alpha_faces.push_back(facep);
+ }
}
}
else
@@ -4510,6 +4553,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
mFaceList.clear();
+
+ if (pAvatarVO)
+ {
+ pAvatarVO->mAttachmentGeometryBytes += group->mGeometryBytes;
+ pAvatarVO->mAttachmentSurfaceArea += group->mSurfaceArea;
+ }
}
static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry");
@@ -4806,17 +4855,20 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
//create/delete/resize vertex buffer if needed
LLVertexBuffer* buffer = NULL;
- LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter);
+
+ { //try to find a buffer to reuse
+ LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter);
- if (found_iter != group->mBufferMap[mask].end())
- {
- if ((U32) buffer_index < found_iter->second.size())
+ if (found_iter != group->mBufferMap[mask].end())
{
- buffer = found_iter->second[buffer_index];
+ if ((U32) buffer_index < found_iter->second.size())
+ {
+ buffer = found_iter->second[buffer_index];
+ }
}
}
- if (!buffer)
+ if (!buffer || !buffer->isWriteable())
{ //create new buffer if needed
buffer = createVertexBuffer(mask, buffer_usage);
buffer->allocateBuffer(geom_count, index_count, TRUE);
@@ -4835,6 +4887,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
}
+ group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize();
+
+
buffer_map[mask][*face_iter].push_back(buffer);
//add face geometry
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 7df50ec815..315616e8a5 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -167,7 +167,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
indices_per_quad * num_quads);
LLVertexBuffer* buff = face->getVertexBuffer();
- if (!buff)
+ if (!buff || !buff->isWriteable())
{
buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index f1c5499d84..afd902201b 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -774,7 +774,7 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
LLStrider<LLColor4U> colorsp;
LLStrider<LLVector2> texcoordsp;
- if (mStarsVerts.isNull())
+ if (mStarsVerts.isNull() || !mStarsVerts->isWriteable())
{
mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW);
mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE);
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index ddbcdfc3f7..6f6411ce3c 100644
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -63,7 +63,7 @@ struct LLWearableArrivedData
LLWearableList::~LLWearableList()
{
- llassert_always(mList.empty()) ;
+ cleanup();
}
void LLWearableList::cleanup()
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 920a9a3752..0da70d398b 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -305,6 +305,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
{
mCurlRequest = new LLCurlEasyRequest();
}
+ if(!mCurlRequest->isValid())
+ {
+ llwarns << "mCurlRequest is invalid." << llendl ;
+
+ delete mCurlRequest ;
+ mCurlRequest = NULL ;
+ return ;
+ }
+
mErrorCert = NULL;
// mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // useful for debugging
@@ -357,10 +366,20 @@ LLXMLRPCTransaction::Impl::~Impl()
}
delete mCurlRequest;
+ mCurlRequest = NULL ;
}
bool LLXMLRPCTransaction::Impl::process()
{
+ if(!mCurlRequest || !mCurlRequest->isValid())
+ {
+ llwarns << "transaction failed." << llendl ;
+
+ delete mCurlRequest ;
+ mCurlRequest = NULL ;
+ return true ; //failed, quit.
+ }
+
switch(mStatus)
{
case LLXMLRPCTransaction::StatusComplete:
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 657cdc0e07..c523a78b22 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1217,10 +1217,12 @@ void LLPipeline::restoreGL()
BOOL LLPipeline::canUseVertexShaders()
{
+ static const std::string vertex_shader_enable_feature_string = "VertexShaderEnable";
+
if (sDisableShaders ||
!gGLManager.mHasVertexShader ||
!gGLManager.mHasFragmentShader ||
- !LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") ||
+ !LLFeatureManager::getInstance()->isFeatureAvailable(vertex_shader_enable_feature_string) ||
(assertInitialized() && mVertexShadersLoaded != 1) )
{
return FALSE;
@@ -3765,6 +3767,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
LLAppViewer::instance()->pingMainloopTimeout("Pipeline:ForceVBO");
// Initialize lots of GL state to "safe" values
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -5296,7 +5299,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_state->setConstantAttenuation(0.f);
if (sRenderDeferred)
{
- light_state->setLinearAttenuation(light_radius*1.5f);
+ F32 size = light_radius*1.5f;
+ light_state->setLinearAttenuation(size*size);
light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f);
}
else
@@ -5318,7 +5322,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_state->setSpotCutoff(90.f);
light_state->setSpotExponent(2.f);
- light_state->setSpecular(LLColor4::black);
+ const LLColor4 specular(0.f, 0.f, 0.f, 0.f);
+ light_state->setSpecular(specular);
}
else // omnidirectional (point) light
{
@@ -6333,17 +6338,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
- U32 res_mod = RenderResolutionDivisor;
-
LLVector2 tc1(0,0);
LLVector2 tc2((F32) mScreen.getWidth()*2,
(F32) mScreen.getHeight()*2);
- if (res_mod > 1)
- {
- tc2 /= (F32) res_mod;
- }
-
LLFastTimer ftm(FTM_RENDER_BLOOM);
gGL.color4f(1,1,1,1);
LLGLDepthTest depth(GL_FALSE);
@@ -6807,7 +6805,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
mFXAABuffer.bindTexture(0, channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
-
+
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+
F32 scale_x = (F32) width/mFXAABuffer.getWidth();
F32 scale_y = (F32) height/mFXAABuffer.getHeight();
shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
@@ -6827,11 +6831,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
}
else
{
- if (res_mod > 1)
- {
- tc2 /= (F32) res_mod;
- }
-
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
buff->allocateBuffer(3,0,TRUE);
@@ -7458,8 +7457,7 @@ void LLPipeline::renderDeferredLighting()
F32 s = volume->getLightRadius()*1.5f;
LLColor3 col = volume->getLightColor();
- col *= volume->getLightIntensity();
-
+
if (col.magVecSquared() < 0.001f)
{
continue;
@@ -7572,8 +7570,7 @@ void LLPipeline::renderDeferredLighting()
setupSpotLight(gDeferredSpotLightProgram, drawablep);
LLColor3 col = volume->getLightColor();
- col *= volume->getLightIntensity();
-
+
//vertex positions are encoded so the 3 bits of their vertex index
//correspond to their axis facing, with bit position 3,2,1 matching
//axis facing x,y,z, bit set meaning positive facing, bit clear
@@ -7682,8 +7679,7 @@ void LLPipeline::renderDeferredLighting()
setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
LLColor3 col = volume->getLightColor();
- col *= volume->getLightIntensity();
-
+
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
@@ -9428,7 +9424,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
assertInitialized();
- BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID());
+ bool muted = avatar->isVisuallyMuted();
pushRenderTypeMask();
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 2815d736e4..9c78048c46 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -432,34 +432,35 @@ public:
enum LLRenderDebugMask
{
- RENDER_DEBUG_COMPOSITION = 0x0000001,
- RENDER_DEBUG_VERIFY = 0x0000002,
- RENDER_DEBUG_BBOXES = 0x0000004,
- RENDER_DEBUG_OCTREE = 0x0000008,
- RENDER_DEBUG_WIND_VECTORS = 0x0000010,
- RENDER_DEBUG_OCCLUSION = 0x0000020,
- RENDER_DEBUG_POINTS = 0x0000040,
- RENDER_DEBUG_TEXTURE_PRIORITY = 0x0000080,
- RENDER_DEBUG_TEXTURE_AREA = 0x0000100,
- RENDER_DEBUG_FACE_AREA = 0x0000200,
- RENDER_DEBUG_PARTICLES = 0x0000400,
- RENDER_DEBUG_GLOW = 0x0000800,
- RENDER_DEBUG_TEXTURE_ANIM = 0x0001000,
- RENDER_DEBUG_LIGHTS = 0x0002000,
- RENDER_DEBUG_BATCH_SIZE = 0x0004000,
- RENDER_DEBUG_ALPHA_BINS = 0x0008000,
- RENDER_DEBUG_RAYCAST = 0x0010000,
- RENDER_DEBUG_SHAME = 0x0020000,
- RENDER_DEBUG_SHADOW_FRUSTA = 0x0040000,
- RENDER_DEBUG_SCULPTED = 0x0080000,
- RENDER_DEBUG_AVATAR_VOLUME = 0x0100000,
- RENDER_DEBUG_BUILD_QUEUE = 0x0200000,
- RENDER_DEBUG_AGENT_TARGET = 0x0400000,
- RENDER_DEBUG_UPDATE_TYPE = 0x0800000,
- RENDER_DEBUG_PHYSICS_SHAPES = 0x1000000,
- RENDER_DEBUG_NORMALS = 0x2000000,
- RENDER_DEBUG_LOD_INFO = 0x4000000,
- RENDER_DEBUG_RENDER_COMPLEXITY = 0x8000000
+ RENDER_DEBUG_COMPOSITION = 0x00000001,
+ RENDER_DEBUG_VERIFY = 0x00000002,
+ RENDER_DEBUG_BBOXES = 0x00000004,
+ RENDER_DEBUG_OCTREE = 0x00000008,
+ RENDER_DEBUG_WIND_VECTORS = 0x00000010,
+ RENDER_DEBUG_OCCLUSION = 0x00000020,
+ RENDER_DEBUG_POINTS = 0x00000040,
+ RENDER_DEBUG_TEXTURE_PRIORITY = 0x00000080,
+ RENDER_DEBUG_TEXTURE_AREA = 0x00000100,
+ RENDER_DEBUG_FACE_AREA = 0x00000200,
+ RENDER_DEBUG_PARTICLES = 0x00000400,
+ RENDER_DEBUG_GLOW = 0x00000800,
+ RENDER_DEBUG_TEXTURE_ANIM = 0x00001000,
+ RENDER_DEBUG_LIGHTS = 0x00002000,
+ RENDER_DEBUG_BATCH_SIZE = 0x00004000,
+ RENDER_DEBUG_ALPHA_BINS = 0x00008000,
+ RENDER_DEBUG_RAYCAST = 0x00010000,
+ RENDER_DEBUG_SHAME = 0x00020000,
+ RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000,
+ RENDER_DEBUG_SCULPTED = 0x00080000,
+ RENDER_DEBUG_AVATAR_VOLUME = 0x00100000,
+ RENDER_DEBUG_BUILD_QUEUE = 0x00200000,
+ RENDER_DEBUG_AGENT_TARGET = 0x00400000,
+ RENDER_DEBUG_UPDATE_TYPE = 0x00800000,
+ RENDER_DEBUG_PHYSICS_SHAPES = 0x01000000,
+ RENDER_DEBUG_NORMALS = 0x02000000,
+ RENDER_DEBUG_LOD_INFO = 0x04000000,
+ RENDER_DEBUG_RENDER_COMPLEXITY = 0x08000000,
+ RENDER_DEBUG_ATTACHMENT_BYTES = 0x10000000,
};
public:
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 8702ebde2a..e4a8622a4b 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -137,6 +137,7 @@ with the same filename but different name
<texture name="Command_MiniCart_Icon" file_name="toolbar_icons/mini_cart.png" preload="true" />
<texture name="Command_MiniMap_Icon" file_name="toolbar_icons/mini_map.png" preload="true" />
<texture name="Command_Move_Icon" file_name="toolbar_icons/move.png" preload="true" />
+ <texture name="Command_Outbox_Icon" file_name="toolbar_icons/outbox.png" preload="true" />
<texture name="Command_People_Icon" file_name="toolbar_icons/people.png" preload="true" />
<texture name="Command_Picks_Icon" file_name="toolbar_icons/picks.png" preload="true" />
<texture name="Command_Places_Icon" file_name="toolbar_icons/places.png" preload="true" />
@@ -386,22 +387,9 @@ with the same filename but different name
<texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" />
<texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" />
- <texture name="OutboxPush_Disabled" file_name="icons/OutboxPush_Disabled.png" preload="true" />
- <texture name="OutboxPush_Off" file_name="icons/OutboxPush_Off.png" preload="true" />
- <texture name="OutboxPush_On" file_name="icons/OutboxPush_On.png" preload="true" />
- <texture name="OutboxPush_On_Over" file_name="icons/OutboxPush_On_Over.png" preload="true" />
- <texture name="OutboxPush_Over" file_name="icons/OutboxPush_Over.png" preload="true" />
- <texture name="OutboxPush_Press" file_name="icons/OutboxPush_Press.png" preload="true" />
- <texture name="OutboxPush_Progress_1" file_name="icons/OutboxPush_Progress_1.png" preload="true" />
- <texture name="OutboxPush_Progress_2" file_name="icons/OutboxPush_Progress_2.png" preload="true" />
- <texture name="OutboxPush_Progress_3" file_name="icons/OutboxPush_Progress_3.png" preload="true" />
- <texture name="OutboxPush_Progress_4" file_name="icons/OutboxPush_Progress_4.png" preload="true" />
- <texture name="OutboxPush_Progress_5" file_name="icons/OutboxPush_Progress_5.png" preload="true" />
- <texture name="OutboxPush_Progress_6" file_name="icons/OutboxPush_Progress_6.png" preload="true" />
- <texture name="OutboxPush_Selected" file_name="icons/OutboxPush_Selected.png" preload="true" />
- <texture name="OutboxPush_Selected_Disabled" file_name="icons/OutboxPush_Selected_Disabled.png" preload="true" />
- <texture name="OutboxPush_Selected_Over" file_name="icons/OutboxPush_Selected_Over.png" preload="true" />
- <texture name="OutboxPush_Selected_Press" file_name="icons/OutboxPush_Selected_Press.png" preload="true" />
+ <texture name="OutboxStatus_Success" file_name="green_checkmark.png" preload="false" />
+ <texture name="OutboxStatus_Warning" file_name="icons/pop_up_caution.png" preload="false" />
+ <texture name="OutboxStatus_Error" file_name="red_x.png" preload="false" />
<texture name="PanOrbit_Off" file_name="bottomtray/PanOrbit_Off.png" preload="false" />
diff --git a/indra/newview/skins/default/textures/toolbar_icons/outbox.png b/indra/newview/skins/default/textures/toolbar_icons/outbox.png
new file mode 100644
index 0000000000..0f3db1c47c
--- /dev/null
+++ b/indra/newview/skins/default/textures/toolbar_icons/outbox.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml
index ba18306686..d695cd1f89 100644
--- a/indra/newview/skins/default/xui/da/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/da/menu_viewer.xml
@@ -20,8 +20,6 @@
<menu_item_call label="Væk" name="Set Away"/>
<menu_item_call label="Optaget" name="Set Busy"/>
</menu>
- <menu_item_call label="Anmod om administrator status" name="Request Admin Options"/>
- <menu_item_call label="Stop administrator status" name="Leave Admin Options"/>
<menu_item_call label="Afslut [APP_NAME]" name="Quit"/>
</menu>
<menu label="Kommunikér" name="Communicate">
@@ -36,11 +34,10 @@
<menu_item_check label="Søg" name="Search"/>
<menu_item_call label="Foto" name="Take Snapshot"/>
<menu_item_call label="Opret landemærke for dette sted" name="Create Landmark Here"/>
- <menu label="Profil for sted" name="Land">
- <menu_item_call label="Profil for sted" name="Place Profile"/>
- <menu_item_call label="Om land" name="About Land"/>
- <menu_item_call label="Region/Estate" name="Region/Estate"/>
- </menu>
+ <menu_item_separator/>
+ <menu_item_call label="Profil for sted" name="Place Profile"/>
+ <menu_item_call label="Om land" name="About Land"/>
+ <menu_item_call label="Region/Estate" name="Region/Estate"/>
<menu_item_call label="Køb dette land" name="Buy Land"/>
<menu_item_call label="Mit land" name="My Land"/>
<menu label="Vis" name="LandShow">
@@ -56,7 +53,7 @@
</menu>
<menu_item_call label="Teleport hjem" name="Teleport Home"/>
<menu_item_call label="Sæt dette sted som &apos;Hjem&apos;" name="Set Home to Here"/>
- <menu label="Sol" name="Environment Settings">
+ <menu label="Sol" name="Sun">
<menu_item_call label="Solopgang" name="Sunrise"/>
<menu_item_call label="Middag" name="Noon"/>
<menu_item_call label="Solnedgang" name="Sunset"/>
@@ -155,22 +152,22 @@
<menu_item_check label="Vis muse-sigte" name="ShowCrosshairs"/>
</menu>
<menu label="Gengivelsestyper" name="Rendering Types">
- <menu_item_check label="Simpel" name="Simple"/>
- <menu_item_check label="Alpha" name="Alpha"/>
- <menu_item_check label="Træer" name="Tree"/>
- <menu_item_check label="Avatarer" name="Character"/>
- <menu_item_check label="Surface Patch" name="Surface Patch"/>
- <menu_item_check label="Himmel" name="Sky"/>
- <menu_item_check label="Vand" name="Water"/>
- <menu_item_check label="Jord" name="Ground"/>
- <menu_item_check label="Volume" name="Volume"/>
- <menu_item_check label="Græs" name="Grass"/>
- <menu_item_check label="Skyer" name="Clouds"/>
- <menu_item_check label="Partikler" name="Particles"/>
- <menu_item_check label="Bump" name="Bump"/>
+ <menu_item_check label="Simpel" name="Rendering Type Simple"/>
+ <menu_item_check label="Alpha" name="Rendering Type Alpha"/>
+ <menu_item_check label="Træer" name="Rendering Type Tree"/>
+ <menu_item_check label="Avatarer" name="Rendering Type Character"/>
+ <menu_item_check label="Surface Patch" name="Rendering Type Surface Patch"/>
+ <menu_item_check label="Himmel" name="Rendering Type Sky"/>
+ <menu_item_check label="Vand" name="Rendering Type Water"/>
+ <menu_item_check label="Jord" name="Rendering Type Ground"/>
+ <menu_item_check label="Volume" name="Rendering Type Volume"/>
+ <menu_item_check label="Græs" name="Rendering Type Grass"/>
+ <menu_item_check label="Skyer" name="Rendering Type Clouds"/>
+ <menu_item_check label="Partikler" name="Rendering Type Particles"/>
+ <menu_item_check label="Bump" name="Rendering Type Bump"/>
</menu>
<menu label="Gengivelsesegenskaber" name="Rendering Features">
- <menu_item_check label="UI" name="UI"/>
+ <menu_item_check label="UI" name="ToggleUI"/>
<menu_item_check label="Valgte" name="Selected"/>
<menu_item_check label="Fremhævede" name="Highlighted"/>
<menu_item_check label="Dynamiske teksturer" name="Dynamic Textures"/>
@@ -182,10 +179,7 @@
<menu_item_call label="Tøm gruppe cache" name="ClearGroupCache"/>
<menu_item_check label="Muse udjævning" name="Mouse Smoothing"/>
<menu label="Shortcuts" name="Shortcuts">
- <menu_item_call label="Billede (L$[COST])..." name="Upload Image"/>
- <menu_item_check label="Søg" name="Search"/>
<menu_item_call label="Frigør taster" name="Release Keys"/>
- <menu_item_call label="Sæt UI størrelse til standard" name="Set UI Size to Default"/>
<menu_item_check label="Vis avanceret menu (gammel genvej)" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="Luk vindue" name="Close Window"/>
<menu_item_call label="Luk alle vinduer" name="Close All Windows"/>
@@ -194,13 +188,6 @@
<menu_item_check label="&quot;Joystick Flycam&quot;" name="Joystick Flycam"/>
<menu_item_call label="Nulstil udsyn" name="Reset View"/>
<menu_item_call label="Se på den sidste der chattede" name="Look at Last Chatter"/>
- <menu label="Vælg byggeværktøj" name="Select Tool">
- <menu_item_call label="Fokuseringsværktøj" name="Focus"/>
- <menu_item_call label="Flyt værktøj" name="Move"/>
- <menu_item_call label="Redigeringsværktøj" name="Edit"/>
- <menu_item_call label="Opret værktøj" name="Create"/>
- <menu_item_call label="Land værktøj" name="Land"/>
- </menu>
<menu_item_call label="Zoom ind" name="Zoom In"/>
<menu_item_call label="Zoom standard" name="Zoom Default"/>
<menu_item_call label="Zoom ud" name="Zoom Out"/>
@@ -276,9 +263,8 @@
<menu_item_call label="Mist en netværkspakke" name="Drop a Packet"/>
</menu>
<menu_item_call label="Stød, skub &amp; slag" name="Bumps, Pushes &amp;amp; Hits"/>
- <menu label="Verden" name="World">
+ <menu label="Verden" name="DevelopWorld">
<menu_item_check label="Vælg anden sol end region" name="Sim Sun Override"/>
- <menu_item_check label="Pejlelys blink effekt" name="Cheesy Beacon"/>
<menu_item_check label="Fast vejr" name="Fixed Weather"/>
<menu_item_call label="Dump Region Object Cache" name="Dump Region Object Cache"/>
</menu>
@@ -300,11 +286,11 @@
</menu>
<menu label="Avatar" name="Character">
<menu label="Grab Baked Texture" name="Grab Baked Texture">
- <menu_item_call label="Iris" name="Iris"/>
- <menu_item_call label="Hovede" name="Head"/>
- <menu_item_call label="Overkrop" name="Upper Body"/>
- <menu_item_call label="Underkrop" name="Lower Body"/>
- <menu_item_call label="Nederdel" name="Skirt"/>
+ <menu_item_call label="Iris" name="Grab Iris"/>
+ <menu_item_call label="Hovede" name="Grab Head"/>
+ <menu_item_call label="Overkrop" name="Grab Upper Body"/>
+ <menu_item_call label="Underkrop" name="Grab Lower Body"/>
+ <menu_item_call label="Nederdel" name="Grab Skirt"/>
</menu>
<menu label="Avatar tests" name="Character Tests">
<menu_item_call label="Skift avatar geometri" name="Toggle Character Geometry"/>
@@ -326,8 +312,8 @@
<menu_item_check label="Vis administrationsmenu" name="View Admin Options"/>
</menu>
<menu label="Administrér" name="Admin">
- <menu label="Object">
- <menu_item_call label="Tag kopi" name="Take Copy"/>
+ <menu label="Object" name="AdminObject">
+ <menu_item_call label="Tag kopi" name="Admin Take Copy"/>
<menu_item_call label="Gennemtving ejer til mig" name="Force Owner To Me"/>
<menu_item_call label="Gennemtving ejer tolerance" name="Force Owner Permissive"/>
<menu_item_call label="Slet" name="Delete"/>
diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml
index 145cc1e30b..b4c28daac9 100644
--- a/indra/newview/skins/default/xui/de/floater_about.xml
+++ b/indra/newview/skins/default/xui/de/floater_about.xml
@@ -67,32 +67,34 @@ Voice-Serverversion: [VOICE_VERSION]
<panel label="Lizenzen" name="licenses_panel">
<text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion.
-APR Copyright (C) 2000-2004 The Apache Software Foundation.
-Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
-cURL Copyright (C) 1996-2002, Daniel Stenberg (daniel@haxx.se).
-DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
-expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
-FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
-GL Copyright (C) 1999-2004 Brian Paul.
-GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University sowie David Luebke, Brenden Schubert, University of Virginia.
-google-perftools Copyright (c) 2005, Google Inc.
-Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
-jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW).
-jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
-ogg/vorbis Copyright (C) 2001, Xiphophorus.
-OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
-PCRE Copyright (c) 1997-2008 University of Cambridge.
-SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga.
-SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com).
-xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
-zlib Copyright (C) 1995-2002 Jean-loup Gailly und Mark Adler.
-google-perftools Copyright (c) 2005, Google Inc.
+ APR Copyright (C) 2000-2004 The Apache Software Foundation.
+ Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2002, Daniel Stenberg (daniel@haxx.se).
+ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
+ expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+ FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ GL Copyright (C) 1999-2004 Brian Paul.
+ GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University sowie David Luebke, Brenden Schubert, University of Virginia.
+ google-perftools Copyright (c) 2005, Google Inc.
+ Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
+ jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW).
+ jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
+ ogg/vorbis Copyright (C) 2001, Xiphophorus.
+ OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2008 University of Cambridge.
+ SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga.
+ SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com).
+ xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
+ zlib Copyright (C) 1995-2002 Jean-loup Gailly und Mark Adler.
+ google-perftools Copyright (c) 2005, Google Inc.
-Second Life Viewer verwendet Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (und Lizenzgeber). Alle Rechte vorbehalten. Details siehe www.havok.com.
+ Second Life Viewer verwendet Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (und Lizenzgeber). Alle Rechte vorbehalten. Details siehe www.havok.com.
-Alle Rechte vorbehalten. Details siehe licenses.txt.
+ Diese Software enthält von der NVIDIA Corporation bereitgestellten Quellcode.
-Audiocodierung für Voice-Chat: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
+ Alle Rechte vorbehalten. Details siehe licenses.txt.
+
+ Audiocodierung für Voice-Chat: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
</text_editor>
</panel>
</tab_container>
diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml
index 3cf3a16247..b893ab79e5 100644
--- a/indra/newview/skins/default/xui/de/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_about_land.xml
@@ -130,7 +130,7 @@
Traffic:
</text>
<text name="DwellText">
- 0
+ Laden...
</text>
<button label="Land kaufen" label_selected="Land kaufen..." name="Buy Land..."/>
<button label="Linden-Verkauf" label_selected="Linden-Verkauf..." name="Linden Sale..." tool_tip="Land muss Eigentum und auf Inhalt gesetzt sein und nicht zur Auktion stehen."/>
@@ -310,13 +310,15 @@ Nur große Parzellen können in der Suche aufgeführt werden.
Kein Stoßen (regional)
</panel.string>
<panel.string name="see_avs_text">
- Auf dieser Parzelle Einwohner sehen und mit ihnen chatten
+ Avatare auf anderen Parzellen können
</panel.string>
<text name="allow_label">
Anderen Einwohnern gestatten:
</text>
- <check_box label="Terrain bearbeiten" name="edit land check" tool_tip="Falls aktiviert, kann jeder Ihr Land terraformen. Am besten ist es, wenn Sie diese Option deaktiviert lassen. Sie können Ihr eigenes Land jederzeit bearbeiten."/>
- <check_box label="Fliegen" name="check fly" tool_tip="Falls aktiviert, können Einwohner auf Ihrem Land fliegen. Falls nicht aktiviert, können Einwohner lediglich auf Ihr Land fliegen und dort landen (dann jedoch nicht wieder weiterfliegen) oder über Ihr Land hinweg fliegen."/>
+ <text name="allow_label0">
+ Fliegen:
+ </text>
+ <check_box label="Jeder" name="check fly" tool_tip="Falls aktiviert, können Einwohner auf Ihrem Land fliegen. Falls nicht aktiviert, können Einwohner lediglich auf Ihr Land fliegen und dort landen (dann jedoch nicht wieder weiterfliegen) oder über Ihr Land hinweg fliegen."/>
<text name="allow_label2">
Bauen:
</text>
@@ -332,9 +334,6 @@ Nur große Parzellen können in der Suche aufgeführt werden.
</text>
<check_box label="Jeder" name="check other scripts"/>
<check_box label="Gruppe" name="check group scripts"/>
- <text name="land_options_label">
- Landoptionen:
- </text>
<check_box label="Sicher (kein Schaden)" name="check safe" tool_tip="Falls aktiviert, wird Land auf Option „Sicher“ eingestellt, Kampfschäden sind deaktiviert. Ansonsten sind Kampfschäden aktiviert."/>
<check_box label="Kein Stoßen" name="PushRestrictCheck" tool_tip="Verhindert Stoßen durch Skripte. Durch Aktivieren dieser Option verhindern Sie störendes Verhalten auf Ihrem Land."/>
<check_box label="Ort in Suche anzeigen (30 L$/Woche)" name="ShowDirectoryCheck" tool_tip="Diese Parzelle in Suchergebnissen anzeigen."/>
@@ -375,9 +374,9 @@ Nur große Parzellen können in der Suche aufgeführt werden.
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/>
<text name="allow_label5">
- Einwohnern auf anderen Parzellen Folgendes gestatten:
+ Avatare auf dieser Parzelle sehen und mit ihnen chatten
</text>
- <check_box label="Avatare sehen" name="SeeAvatarsCheck" tool_tip="Gestattet sowohl Einwohnern auf anderen Parzellen, Einwohner auf dieser Parzelle zu sehen und mit ihnen zu chatten, als auch Ihnen, diese Einwohner auf anderen Parzellen zu sehen und mit ihnen zu chatten."/>
+ <check_box label="Avatare sehen" name="SeeAvatarsCheck" tool_tip="Gestattet sowohl Avataren auf anderen Parzellen, Avatare auf dieser Parzelle zu sehen und mit ihnen zu chatten, als auch Ihnen, diese Avatare auf anderen Parzellen zu sehen und mit ihnen zu chatten."/>
<text name="landing_point">
Landepunkt: [LANDING]
</text>
diff --git a/indra/newview/skins/default/xui/de/floater_avatar.xml b/indra/newview/skins/default/xui/de/floater_avatar.xml
index 1470c4bcd6..ba0dd54d96 100644
--- a/indra/newview/skins/default/xui/de/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/de/floater_avatar.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Avatar" title="AVATAR-AUSWAHL"/>
+<floater name="Avatar" title="AVATAR AUSWÄHLEN"/>
diff --git a/indra/newview/skins/default/xui/de/floater_buy_currency.xml b/indra/newview/skins/default/xui/de/floater_buy_currency.xml
index e766b622f7..65926c088c 100644
--- a/indra/newview/skins/default/xui/de/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/de/floater_buy_currency.xml
@@ -46,7 +46,7 @@
[AMT] L$
</text>
<text name="currency_links">
- [http://www.secondlife.com/my/account/payment_method_management.php?lang=de-DE Zahlungsart] | [http://www.secondlife.com/my/account/currency.php?lang=de-DE Währung]
+ [http://www.secondlife.com/my/account/payment_method_management.php Zahlungsart] | [http://www.secondlife.com/my/account/currency.php Währung]
</text>
<text name="exchange_rate_note">
Geben Sie den Betrag erneut ein, um die aktuellste Umtauschrate anzuzeigen.
diff --git a/indra/newview/skins/default/xui/de/floater_camera.xml b/indra/newview/skins/default/xui/de/floater_camera.xml
index 7e9ebdb643..163ef87d8c 100644
--- a/indra/newview/skins/default/xui/de/floater_camera.xml
+++ b/indra/newview/skins/default/xui/de/floater_camera.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="camera_floater" title="ANSICHT">
+<floater name="camera_floater" title="KAMERASTEUERUNGEN">
<floater.string name="rotate_tooltip">
Kamera um Fokus drehen
</floater.string>
diff --git a/indra/newview/skins/default/xui/de/floater_chat_bar.xml b/indra/newview/skins/default/xui/de/floater_chat_bar.xml
index dc5a7cd681..2464a55665 100644
--- a/indra/newview/skins/default/xui/de/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/de/floater_chat_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="chat_bar" title="CHAT IN DER NÄHE">
- <panel>
+ <panel name="bottom_panel">
<line_editor label="Zum Chatten hier klicken." name="chat_box" tool_tip="Eingabetaste zum Sprechen, Strg+Eingabe zum Rufen"/>
<button name="show_nearby_chat" tool_tip="Chatprotokoll in der Nähe ein-/ausblenden"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/floater_hardware_settings.xml b/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
index 9644bbbaea..ca081aafae 100644
--- a/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
@@ -4,7 +4,7 @@
Filtern:
</text>
<check_box label="Anisotropische Filterung (langsamer, wenn aktiviert)" name="ani"/>
- <text name="Antialiasing:">
+ <text name="antialiasing label">
Antialiasing:
</text>
<combo_box label="Antialiasing" name="fsaa">
diff --git a/indra/newview/skins/default/xui/de/floater_model_preview.xml b/indra/newview/skins/default/xui/de/floater_model_preview.xml
index 7f6cd9944f..4af8d67686 100644
--- a/indra/newview/skins/default/xui/de/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_model_preview.xml
@@ -4,6 +4,9 @@
<string name="status_parse_error">
Fehler: Fehler beim DAE-Parsen – Details siehe Protokoll.
</string>
+ <string name="status_material_mismatch">
+ Fehler: Das Material des Modells ist keine Teilmenge des Referenzmodells.
+ </string>
<string name="status_reading_file">
Laden...
</string>
@@ -137,7 +140,7 @@
</panel>
<panel name="physics analysis">
<text name="method_label">
- Schritt 2: Analyse
+ Schritt 2: Analysieren
</text>
<text name="analysis_method_label">
Methode:
diff --git a/indra/newview/skins/default/xui/de/floater_model_wizard.xml b/indra/newview/skins/default/xui/de/floater_model_wizard.xml
index 354a505901..a90f36f202 100644
--- a/indra/newview/skins/default/xui/de/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/de/floater_model_wizard.xml
@@ -20,6 +20,9 @@
Hochzuladende Modelldatei auswählen
</text>
<button label="Durchsuchen..." label_selected="Durchsuchen..." name="browse"/>
+ <text name="Model types">
+ Second Life unterstützt COLLADA-Dateien (.dae).
+ </text>
<text name="dimensions">
X Y Z
</text>
diff --git a/indra/newview/skins/default/xui/de/floater_moveview.xml b/indra/newview/skins/default/xui/de/floater_moveview.xml
index e8cc77c038..c1c8271310 100644
--- a/indra/newview/skins/default/xui/de/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/de/floater_moveview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="move_floater" title="BEWEGEN">
+<floater name="move_floater" title="GEHEN / RENNEN / FLIEGEN">
<string name="walk_forward_tooltip">
Vorwärts gehen (Nach-oben-Pfeil oder W drücken)
</string>
diff --git a/indra/newview/skins/default/xui/de/floater_snapshot.xml b/indra/newview/skins/default/xui/de/floater_snapshot.xml
index ae68c71a80..798461c007 100644
--- a/indra/newview/skins/default/xui/de/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/de/floater_snapshot.xml
@@ -3,73 +3,63 @@
<floater.string name="unknown">
unbekannt
</floater.string>
- <radio_group label="Fototyp" name="snapshot_type_radio">
- <radio_item label="E-Mail" name="postcard"/>
- <radio_item label="Mein Inventar ([AMOUNT] L$)" name="texture"/>
- <radio_item label="Auf meinem Computer speichern" name="local"/>
- </radio_group>
+ <string name="postcard_progress_str">
+ E-Mail senden
+ </string>
+ <string name="profile_progress_str">
+ Posten
+ </string>
+ <string name="inventory_progress_str">
+ Speichern im Inventar
+ </string>
+ <string name="local_progress_str">
+ Speichern auf Computer
+ </string>
+ <string name="profile_succeeded_str">
+ Bild hochgeladen
+ </string>
+ <string name="postcard_succeeded_str">
+ E-Mail gesendet!
+ </string>
+ <string name="inventory_succeeded_str">
+ Im Inventar gespeichert!
+ </string>
+ <string name="local_succeeded_str">
+ Auf Computer gespeichert!
+ </string>
+ <string name="profile_failed_str">
+ Fehler beim Hochladen des Bilds in Ihr Profil.
+ </string>
+ <string name="postcard_failed_str">
+ Fehler beim Senden der E-Mail.
+ </string>
+ <string name="inventory_failed_str">
+ Fehler beim Speichern im Inventar.
+ </string>
+ <string name="local_failed_str">
+ Fehler beim Speichern auf dem Computer.
+ </string>
+ <button name="advanced_options_btn" tool_tip="Erweiterte Optionen"/>
+ <text name="image_res_text">
+ [WIDTH] x [HEIGHT] px
+ </text>
<text name="file_size_label">
[SIZE] KB
</text>
- <button label="Foto aktualisieren" name="new_snapshot_btn"/>
- <button label="Senden" name="send_btn"/>
- <button label="Speichern ([AMOUNT] L$)" name="upload_btn"/>
- <flyout_button label="Speichern" name="save_btn" tool_tip="Bild als Datei speichern">
- <flyout_button.item label="Speichern" name="save_item"/>
- <flyout_button.item label="Speichern unter..." name="saveas_item"/>
- </flyout_button>
- <button label="Mehr" name="more_btn" tool_tip="Erweiterte Optionen"/>
- <button label="Weniger" name="less_btn" tool_tip="Erweiterte Optionen"/>
- <button label="Abbrechen" name="discard_btn"/>
- <text name="type_label2">
- Größe
- </text>
- <text name="format_label">
- Format
- </text>
- <combo_box label="Auflösung" name="postcard_size_combo">
- <combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="Benutzerdefiniert" name="Custom"/>
- </combo_box>
- <combo_box label="Auflösung" name="texture_size_combo">
- <combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
- <combo_box.item label="Klein (128x128)" name="Small(128x128)"/>
- <combo_box.item label="Mittel (256x256)" name="Medium(256x256)"/>
- <combo_box.item label="Groß (512x512)" name="Large(512x512)"/>
- <combo_box.item label="Benutzerdefiniert" name="Custom"/>
- </combo_box>
- <combo_box label="Auflösung" name="local_size_combo">
- <combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
- <combo_box.item label="320x240" name="320x240"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1280x1024" name="1280x1024"/>
- <combo_box.item label="1600x1200" name="1600x1200"/>
- <combo_box.item label="Benutzerdefiniert" name="Custom"/>
- </combo_box>
- <combo_box label="Format" name="local_format_combo">
- <combo_box.item label="PNG" name="PNG"/>
- <combo_box.item label="JPEG" name="JPEG"/>
- <combo_box.item label="BMP" name="BMP"/>
- </combo_box>
- <spinner label="Breite" name="snapshot_width"/>
- <spinner label="Größe" name="snapshot_height"/>
- <check_box label="Seitenverhältnis beibehalten" name="keep_aspect_check"/>
- <slider label="Bildqualität" name="image_quality_slider"/>
- <text name="layer_type_label">
- Aufnehmen:
- </text>
- <combo_box label="Bildlayer" name="layer_types">
- <combo_box.item label="Farben" name="Colors"/>
- <combo_box.item label="Tiefe" name="Depth"/>
- </combo_box>
- <check_box label="Schnittstelle" name="ui_check"/>
- <check_box label="HUDs" name="hud_check"/>
- <check_box label="Nach dem Speichern offen lassen" name="keep_open_check"/>
- <check_box label="Frame einfrieren (Vollbild)" name="freeze_frame_check"/>
- <check_box label="Automatisch aktualisieren" name="auto_snapshot_check"/>
+ <panel name="advanced_options_panel">
+ <text name="advanced_options_label">
+ ERWEITERTE OPTIONEN
+ </text>
+ <text name="layer_type_label">
+ Aufnahme:
+ </text>
+ <combo_box label="Bildebenen" name="layer_types">
+ <combo_box.item label="Farben" name="Colors"/>
+ <combo_box.item label="Tiefe" name="Depth"/>
+ </combo_box>
+ <check_box label="Schnittstelle" name="ui_check"/>
+ <check_box label="HUDs" name="hud_check"/>
+ <check_box label="Standbild (Vollbild)" name="freeze_frame_check"/>
+ <check_box label="Automatisch aktualisieren" name="auto_snapshot_check"/>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_toybox.xml b/indra/newview/skins/default/xui/de/floater_toybox.xml
index 23ec9c2e58..90e50804d6 100644
--- a/indra/newview/skins/default/xui/de/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/de/floater_toybox.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Toybox" title="SYMBOLLEISTEN ANPASSEN">
+<floater name="Toybox" title="SYMBOLLEISTENSCHALTFLÄCHEN">
<text name="toybox label 1">
Sie können Schaltflächen durch Ziehen zu Symbolleisten hinzufügen oder daraus entfernen.
</text>
<text name="toybox label 2">
Je nach Einstellung erscheinen Schaltflächen wie dargestellt oder nur als Symbol.
</text>
+ <button label="Alle Symbolleisten leeren" label_selected="Alle Symbolleisten leeren" name="btn_clear_all"/>
<button label="Standards wiederherstellen" label_selected="Standards wiederherstellen" name="btn_restore_defaults"/>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_translation_settings.xml b/indra/newview/skins/default/xui/de/floater_translation_settings.xml
new file mode 100644
index 0000000000..3d5d1d46a8
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_translation_settings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_translation_settings" title="ÜBERSETZUNGSEINSTELLUNGEN FÜR CHATS">
+ <string name="bing_api_key_not_verified">
+ Bing-AppID nicht verifiziert. Versuchen Sie es erneut.
+ </string>
+ <string name="google_api_key_not_verified">
+ Google-API-Schlüssel nicht verifiziert. Versuchen Sie es erneut.
+ </string>
+ <string name="bing_api_key_verified">
+ Bing-AppID verifiziert.
+ </string>
+ <string name="google_api_key_verified">
+ Google-API-Schlüssel verifiziert.
+ </string>
+ <check_box label="Maschinenübersetzung beim Chatten aktivieren" name="translate_chat_checkbox"/>
+ <text name="translate_language_label">
+ Chat übersetzen in:
+ </text>
+ <combo_box name="translate_language_combo">
+ <combo_box.item label="Systemstandard" name="System Default Language"/>
+ <combo_box.item label="English (Englisch)" name="English"/>
+ <combo_box.item label="Dansk (Dänisch)" name="Danish"/>
+ <combo_box.item label="Deutsch" name="German"/>
+ <combo_box.item label="Español (Spanisch)" name="Spanish"/>
+ <combo_box.item label="Français (Französisch)" name="French"/>
+ <combo_box.item label="Italiano (Italienisch)" name="Italian"/>
+ <combo_box.item label="Magyar (Ungarisch)" name="Hungarian"/>
+ <combo_box.item label="Nederlands (Holländisch)" name="Dutch"/>
+ <combo_box.item label="Polski (Polnisch)" name="Polish"/>
+ <combo_box.item label="Português (Portugiesisch)" name="Portugese"/>
+ <combo_box.item label="Русский (Russisch)" name="Russian"/>
+ <combo_box.item label="Türkçe (Türkisch)" name="Turkish"/>
+ <combo_box.item label="Українська (Ukrainisch)" name="Ukrainian"/>
+ <combo_box.item label="中文 (正體) (Chinesisch)" name="Chinese"/>
+ <combo_box.item label="日本語 (Japanisch)" name="Japanese"/>
+ <combo_box.item label="한국어 (Koreanisch)" name="Korean"/>
+ </combo_box>
+ <text name="tip">
+ Übersetzungsservice auswählen:
+ </text>
+ <radio_group name="translation_service_rg">
+ <radio_item initial_value="bing" label="Bing Translator" name="bing"/>
+ <radio_item initial_value="google" label="Google Translate" name="google"/>
+ </radio_group>
+ <text name="bing_api_key_label">
+ Bing-[http://www.bing.com/developers/createapp.aspx AppID]:
+ </text>
+ <button label="Verifizieren" name="verify_bing_api_key_btn"/>
+ <text name="google_api_key_label">
+ Google-[http://code.google.com/apis/language/translate/v2/getting_started.html#auth API-Schlüssel]:
+ </text>
+ <button label="Verifizieren" name="verify_google_api_key_btn"/>
+ <text name="google_links_text">
+ [http://code.google.com/apis/language/translate/v2/pricing.html Pricing] | [https://code.google.com/apis/console Statistik]
+ </text>
+ <button label="OK" name="ok_btn"/>
+ <button label="Abbrechen" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_voice_controls.xml b/indra/newview/skins/default/xui/de/floater_voice_controls.xml
index 18d53841b8..5efda4136e 100644
--- a/indra/newview/skins/default/xui/de/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/de/floater_voice_controls.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_voice_controls" title="SPRACHSTEUERUNGEN">
<string name="title_nearby">
- Stimme in der Nähe
+ VOICE-EINSTELLUNGEN
</string>
<string name="title_group">
- Gruppengespräch mit [GROUP]
+ GRUPPENGESPRÄCH MIT [GROUP]
</string>
<string name="title_adhoc">
- Konferenzgespräch
+ KONFERENZGESPRÄCH
</string>
<string name="title_peer_2_peer">
- Gespräch mit [NAME]
+ GESPRÄCH MIT [NAME]
</string>
<string name="no_one_near">
Es ist niemand in der Nähe, der Voice aktiviert hat.
diff --git a/indra/newview/skins/default/xui/de/menu_toolbars.xml b/indra/newview/skins/default/xui/de/menu_toolbars.xml
index cfeae3deca..3fb48e26b2 100644
--- a/indra/newview/skins/default/xui/de/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/de/menu_toolbars.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Toolbars Popup">
- <menu_item_call label="Schaltflächen auswählen..." name="Chose Buttons"/>
+ <menu_item_call label="Diese Schaltfläche entfernen" name="Remove button"/>
+ <menu_item_call label="Symbolleistenschaltflächen..." name="Choose Buttons"/>
<menu_item_check label="Symbole und Beschriftungen" name="icons_with_text"/>
<menu_item_check label="Nur Symbole" name="icons_only"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml
index 90b2cfbc41..a81874bee9 100644
--- a/indra/newview/skins/default/xui/de/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/de/menu_viewer.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu_bar name="Main Menu">
<menu label="Ich" name="Me">
- <menu_item_call label="Dashboard..." name="Manage My Account">
- <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=de"/>
- </menu_item_call>
<menu_item_call label="Profil..." name="Profile"/>
<menu_item_call label="Aussehen..." name="ChangeOutfit"/>
+ <menu_item_call label="Avatar auswählen..." name="Avatar Picker"/>
<menu_item_check label="Inventar..." name="Inventory"/>
- <menu_item_check label="Gesten..." name="Gestures"/>
- <menu_item_check label="Stimme..." name="ShowVoice"/>
+ <menu_item_call label="Neues Inventarfenster" name="NewInventoryWindow"/>
+ <menu_item_call label="Orte..." name="Places"/>
+ <menu_item_call label="Auswahlen..." name="Picks"/>
+ <menu_item_call label="Kamerasteuerungen..." name="Camera Controls"/>
<menu label="Bewegung" name="Movement">
<menu_item_call label="Hinsetzen" name="Sit Down Here"/>
<menu_item_check label="Fliegen" name="Fly"/>
@@ -22,34 +22,39 @@
<menu_item_call label="Admin-Status anfordern" name="Request Admin Options"/>
<menu_item_call label="Admin-Status verlassen" name="Leave Admin Options"/>
<menu_item_call label="L$ kaufen" name="Buy and Sell L$"/>
+ <menu_item_call label="Kontoübersicht..." name="Manage My Account">
+ <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=de"/>
+ </menu_item_call>
<menu_item_call label="Einstellungen..." name="Preferences"/>
- <menu_item_call label="Symbolleisten..." name="Toolbars"/>
+ <menu_item_call label="Symbolleistenschaltflächen..." name="Toolbars"/>
<menu_item_call label="Alle Steuerelemente ausblenden" name="Hide UI"/>
<menu_item_call label="[APP_NAME] schließen" name="Quit"/>
</menu>
<menu label="Unterhalten" name="Communicate">
- <menu_item_call label="Meine Freunde" name="My Friends"/>
- <menu_item_call label="Meine Gruppen" name="My Groups"/>
- <menu_item_check label="Chat in der Nähe" name="Nearby Chat"/>
+ <menu_item_check label="Chat..." name="Nearby Chat"/>
+ <menu_item_check label="Sprechen" name="Speak"/>
+ <menu_item_check label="Voice-Einstellungen..." name="Nearby Voice"/>
+ <menu_item_check label="Voice-Morphing..." name="ShowVoice"/>
+ <menu_item_check label="Gesten..." name="Gestures"/>
+ <menu_item_call label="Freunde" name="My Friends"/>
+ <menu_item_call label="Gruppen" name="My Groups"/>
<menu_item_call label="Leute in der Nähe" name="Active Speakers"/>
- <menu_item_check label="Stimme in der Nähe" name="Nearby Voice"/>
</menu>
<menu label="Welt" name="World">
- <menu_item_check label="Minikarte" name="Mini-Map"/>
+ <menu_item_call label="Landmarke für diesen Ort setzen" name="Create Landmark Here"/>
+ <menu_item_call label="Ziele..." name="Destinations"/>
<menu_item_check label="Karte" name="World Map"/>
+ <menu_item_check label="Minikarte" name="Mini-Map"/>
<menu_item_check label="Suchen" name="Search"/>
+ <menu_item_call label="Nach Hause teleportieren" name="Teleport Home"/>
+ <menu_item_call label="Hier als Zuhause wählen" name="Set Home to Here"/>
<menu_item_call label="Foto" name="Take Snapshot"/>
- <menu_item_call label="Landmarke für diesen Ort setzen" name="Create Landmark Here"/>
- <menu label="Ortsprofil" name="Land">
- <menu_item_call label="Ortsprofil" name="Place Profile"/>
- <menu_item_call label="Land-Info" name="About Land"/>
- <menu_item_call label="Region/Grundbesitz" name="Region/Estate"/>
- </menu>
+ <menu_item_call label="Ortsprofil" name="Place Profile"/>
+ <menu_item_call label="Landinformationen" name="About Land"/>
+ <menu_item_call label="Region/Grundbesitz" name="Region/Estate"/>
+ <menu_item_call label="Mein Landbesitz..." name="My Land"/>
<menu_item_call label="Dieses Land kaufen" name="Buy Land"/>
- <menu_item_call label="Mein Land" name="My Land"/>
<menu label="Anzeigen" name="LandShow">
- <menu_item_check label="Bewegungssteuerung" name="Movement Controls"/>
- <menu_item_check label="Ansichtsteuerung" name="Camera Controls"/>
<menu_item_check label="Bannlinien" name="Ban Lines"/>
<menu_item_check label="Strahlen" name="beacons"/>
<menu_item_check label="Grundstücksgrenzen" name="Property Lines"/>
@@ -58,16 +63,15 @@
<menu_item_check label="Parzelleneigenschaften" name="Parcel Properties"/>
<menu_item_check label="Menü „Erweitert“" name="Show Advanced Menu"/>
</menu>
- <menu_item_call label="Teleport nach Hause" name="Teleport Home"/>
- <menu_item_call label="Hier als Zuhause wählen" name="Set Home to Here"/>
<menu label="Sonne" name="Environment Settings">
<menu_item_call label="Sonnenaufgang" name="Sunrise"/>
<menu_item_call label="Mittag" name="Noon"/>
<menu_item_call label="Sonnenuntergang" name="Sunset"/>
<menu_item_call label="Mitternacht" name="Midnight"/>
+ <menu_item_call label="Regionseinstellungen verwenden" name="Use Region Settings"/>
</menu>
- <menu label="Umgebungs-Editor" name="Enviroment Editor">
- <menu_item_call label="Umgebungseinstellungen..." name="Enviroment Settings"/>
+ <menu label="Umwelt-Editor" name="Environment Editor">
+ <menu_item_call label="Umwelt-Einstellungen..." name="Environment Settings"/>
<menu label="Wasser-Voreinstellungen" name="Water Presets">
<menu_item_call label="Neue Voreinstellung..." name="new_water_preset"/>
<menu_item_call label="Voreinstellung bearbeiten..." name="edit_water_preset"/>
@@ -146,6 +150,7 @@
<menu_item_call label="Wiederholen" name="Redo"/>
</menu>
<menu label="Hilfe" name="Help">
+ <menu_item_call label="Anweisungen..." name="How To"/>
<menu_item_call label="[SECOND_LIFE]-Hilfe" name="Second Life Help"/>
<menu_item_call label="Missbrauch melden" name="Report Abuse"/>
<menu_item_call label="Fehler melden" name="Report Bug"/>
@@ -200,11 +205,10 @@
<menu_item_check label="Plugin Read Thread verwenden" name="Use Plugin Read Thread"/>
<menu_item_call label="Gruppen-Cache löschen" name="ClearGroupCache"/>
<menu_item_check label="Weiche Mausbewegung" name="Mouse Smoothing"/>
+ <menu_item_call label="Tasten freigeben" name="Release Keys"/>
<menu label="Tastaturkürzel" name="Shortcuts">
<menu_item_call label="Bild ([COST] L$)..." name="Upload Image"/>
<menu_item_check label="Suchen" name="Search"/>
- <menu_item_call label="Tasten freigeben" name="Release Keys"/>
- <menu_item_call label="UI-Größe auf Standard setzen" name="Set UI Size to Default"/>
<menu_item_check label="Erweitert-Menü anzeigen - veraltetet" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="Fenster schließen" name="Close Window"/>
<menu_item_call label="Alle Fenster schließen" name="Close All Windows"/>
@@ -290,6 +294,7 @@
<menu_item_check label="Lichter" name="Lights"/>
<menu_item_check label="Gelenkpunkte" name="Collision Skeleton"/>
<menu_item_check label="Raycast" name="Raycast"/>
+ <menu_item_check label="Windvektoren" name="Wind Vectors"/>
<menu_item_check label="Komplexität beim Rendern" name="rendercomplexity"/>
<menu_item_check label="Formen" name="Sculpt"/>
</menu>
@@ -302,7 +307,6 @@
<menu_item_check label="Licht und Schatten" name="Lighting and Shadows"/>
<menu_item_check label="Schatten von Sonne-/Mond-Projektoren" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO und Schattenglättung" name="SSAO and Shadow Smoothing"/>
- <menu_item_check label="Globale Beleuchtung (experimentell)" name="Global Illumination"/>
<menu_item_check label="Fehler in GL beseitigen" name="Debug GL"/>
<menu_item_check label="Fehler in Pipeline beseitigen" name="Debug Pipeline"/>
<menu_item_check label="Automatische Alpha-Masken (aufgeschoben)" name="Automatic Alpha Masks (deferred)"/>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index 72e7ec8eb4..a34b938a7a 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -1124,8 +1124,13 @@ Der Gruppe „[GROUP_NAME]“ [AREA] m² an Land schenken?
<notification name="DisplaySetToSafe">
Es wurden sichere Anzeige-Einstellungen gewählt, da die Option -safe verwendet wurde.
</notification>
- <notification name="DisplaySetToRecommended">
- Es wurden die für Ihre Systemkonfiguration empfohlenen Anzeige-Einstellungen gewählt.
+ <notification name="DisplaySetToRecommendedGPUChange">
+ Die Anzeigeeinstellungen wurden auf die empfohlenen Werte gesetzt, da Ihre Grafikkarte geändert wurde
+von „[LAST_GPU]“
+in „[THIS_GPU]“
+ </notification>
+ <notification name="DisplaySetToRecommendedFeatureChange">
+ Aufgrund einer Änderung des Rendersubsystems wurden die Anzeigeeinstellungen auf die empfohlenen Werte gesetzt.
</notification>
<notification name="ErrorMessage">
[ERROR_MESSAGE]
@@ -1443,7 +1448,7 @@ Zur Installation des Updates muss [APP_NAME] neu gestartet werden.
<usetemplate ignoretext="Bestätigen, bevor Objekte an Ihre Eigentümer zurückgegeben werden" name="okcancelignore" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="GroupLeaveConfirmMember">
- Sie sind Mitglied der Gruppe [GROUP].
+ Sie sind Mitglied der Gruppe &lt;nolink&gt;[GROUP]&lt;/nolink&gt;.
Diese Gruppe verlassen?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
@@ -1926,7 +1931,13 @@ Inventarobjekt(e) verschieben?
<usetemplate ignoretext="Bestätigen, bevor Sitzung beendet wird" name="okcancelignore" notext="Nicht beenden" yestext="Beenden"/>
</notification>
<notification name="ConfirmRestoreToybox">
- Möchten Sie wirklich Ihre Standardschaltflächen und -symbolleisten wiederherstellen?
+ Durch diese Aktion werden Ihre Standardschaltflächen und -symbolleisten wiederhergestellt.
+
+Diese Aktion kann nicht rückgängig gemacht werden.
+ <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
+ </notification>
+ <notification name="ConfirmClearAllToybox">
+ Durch diese Aktion werden alle Schaltflächen zurück in die Toolbox gestellt; die Symbolleisten sind leer.
Diese Aktion kann nicht rückgängig gemacht werden.
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
@@ -2250,14 +2261,16 @@ Wählen Sie ein einzelnes Objekt aus.
Ihre Visitenkarte wurde abgelehnt.
</notification>
<notification name="TeleportToLandmark">
- Sie können an Positionen wie „[NAME]“ teleportieren, wenn Sie rechts in Ihrem Bildschirm die Tafel „Orte“ öffnen und dann die Registerkarte „Meine Landmarken“ auswählen.
-Klicken Sie auf eine Landmarke, um diese auszuwählen. Klicken Sie anschließend auf unten in der Registerkarte auf „Teleportieren“.
-(Sie können auch auf die Landmarke doppelt klicken oder mit rechts auf die Landmarke klicken und dann „Teleportieren“ auswählen).
+ Um zu Orten wie „[NAME]“ zu teleportieren, klicken Sie zuerst auf die Schaltfläche „Orte“
+ und dann im eingeblendeten Fenster auf die Registerkarte „Landmarken“. Klicken Sie auf
+ die gewünschte Landmarke und dann unten im Fenster auf „Teleportieren“.
+ (Sie können auch auf die Landmarke doppelklicken bzw. sie mit der rechten Maustaste ankklicken und dann
+ „Teleportieren“ wählen.)
</notification>
<notification name="TeleportToPerson">
- Sie können Einwohner wie „[NAME]“ kontaktieren, wenn Sie die Tafel „Leute“ auf der rechten Seite Ihres Bildschirms öffnen.
-Wählen Sie den Einwohner aus der Liste aus und klicken Sie unten auf „IM“.
-(Sie können auch auf den Namen doppelt klicken oder mit rechts auf den Namen klicken und dann „IM“ auswählen).
+ Um Einwohner wie „[NAME]“ zu kontaktieren, klicken Sie auf die Schaltfläche „Leute“, wählen Sie eingeblendeten Fenster einen Einwohner aus
+ und klicken Sie unten im Fenster auf „IM“.
+ (Sie können auch auf den Namen doppelklicken bzw. ihn mit der rechten Maustaste anklicken und dann „IM“ wählen.)
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Land kann nicht über Servergrenzen hinweg ausgewählt werden.
@@ -2278,6 +2291,9 @@ Wählen Sie eine kleinere Landfläche.
<notification name="PaymentSent">
[MESSAGE]
</notification>
+ <notification name="PaymentFailure">
+ [MESSAGE]
+ </notification>
<notification name="EventNotification">
Event-Benachrichtigung:
diff --git a/indra/newview/skins/default/xui/de/panel_edit_skin.xml b/indra/newview/skins/default/xui/de/panel_edit_skin.xml
index f167f45e98..60f6919485 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_skin.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skin_panel">
<panel name="avatar_skin_color_panel">
- <texture_picker label="Kopftattoo" name="Head Tattoos" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
- <texture_picker label="Obere Tattoos" name="Upper Tattoos" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
- <texture_picker label="Untere Tattoos" name="Lower Tattoos" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+ <texture_picker label="Kopf" name="Head" tool_tip="Klicken, um ein Bild zu wählen"/>
+ <texture_picker label="Oberkörper" name="Upper Body" tool_tip="Klicken, um ein Bild zu wählen"/>
+ <texture_picker label="Unterkörper" name="Lower Body" tool_tip="Klicken, um ein Bild zu wählen"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/de/panel_postcard_message.xml b/indra/newview/skins/default/xui/de/panel_postcard_message.xml
new file mode 100644
index 0000000000..6eeef8af71
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_postcard_message.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_message">
+ <text name="to_label">
+ An:
+ </text>
+ <text name="name_label">
+ Von:
+ </text>
+ <text name="subject_label">
+ Betreff:
+ </text>
+ <line_editor label="Betreff hier eingeben." name="subject_form"/>
+ <text name="msg_label">
+ Nachricht:
+ </text>
+ <text_editor name="msg_form">
+ Nachricht hier eingeben.
+ </text_editor>
+ <button label="Abbrechen" name="cancel_btn"/>
+ <button label="Senden" name="send_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_postcard_settings.xml b/indra/newview/skins/default/xui/de/panel_postcard_settings.xml
new file mode 100644
index 0000000000..c1a1c0cc46
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_postcard_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_settings">
+ <combo_box label="Auflösung" name="postcard_size_combo">
+ <combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Benutzerdefiniert" name="Custom"/>
+ </combo_box>
+ <layout_stack name="postcard_image_params_ls">
+ <layout_panel name="postcard_image_size_lp">
+ <spinner label="Breite" name="postcard_snapshot_width"/>
+ <spinner label="Höhe" name="postcard_snapshot_height"/>
+ <check_box label="Seitenverhältnis beibehalten" name="postcard_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="postcard_image_format_quality_lp">
+ <slider label="Bildqualität" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
index 04f6c27330..746a561e6c 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
@@ -29,30 +29,5 @@
<check_box label="IM-Chats" name="EnableIMChatPopups" tool_tip="Markieren, um Popups zu sehen, wenn Instant Message eintrifft"/>
<spinner label="Lebenszeit von Toasts für Chat in der Nähe:" name="nearby_toasts_lifetime"/>
<spinner label="Ein-/Ausblenddauer von Toasts für Chat in der Nähe:" name="nearby_toasts_fadingtime"/>
- <check_box name="translate_chat_checkbox"/>
- <text name="translate_chb_label">
- Beim Chatten Maschinenübersetzung verwenden
- </text>
- <text name="translate_language_text">
- Chat übersetzen in:
- </text>
- <combo_box name="translate_language_combobox" width="200">
- <combo_box.item label="Systemstandard" name="System Default Language"/>
- <combo_box.item label="English (Englisch)" name="English"/>
- <combo_box.item label="Dansk (Dänisch)" name="Danish"/>
- <combo_box.item label="Deutsch" name="German"/>
- <combo_box.item label="Español (Spanisch)" name="Spanish"/>
- <combo_box.item label="Français (Französisch)" name="French"/>
- <combo_box.item label="Italiano (Italienisch)" name="Italian"/>
- <combo_box.item label="Magyar (Ungarisch)" name="Hungarian"/>
- <combo_box.item label="Nederlands (Holländisch)" name="Dutch"/>
- <combo_box.item label="Polski (Polnisch)" name="Polish"/>
- <combo_box.item label="Português (Portugiesisch)" name="Portugese"/>
- <combo_box.item label="Русский (Russisch)" name="Russian"/>
- <combo_box.item label="Türkçe (Türkisch)" name="Turkish"/>
- <combo_box.item label="Українська (Ukrainisch)" name="Ukrainian"/>
- <combo_box.item label="中文 (正體) (Chinesisch)" name="Chinese"/>
- <combo_box.item label="日本語 (Japanisch)" name="Japanese"/>
- <combo_box.item label="한국어 (Koreanisch)" name="Korean"/>
- </combo_box>
+ <button label="Übersetzungseinstellungen für Chats" name="ok_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
index 8b18bf8659..8c7ea688d7 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
@@ -15,7 +15,7 @@
Web:
</text>
<radio_group name="use_external_browser">
- <radio_item label="Meinen Browser verwenden (IE, Firefox, Safari)" name="external" tool_tip="Standard Webbrowser des Systems verwenden, um die Hilfe, Weblinks usw. anzuzeigen. Bei Vollbildmodus nicht empfohlen." value="1"/>
+ <radio_item label="Meinen Browser verwenden (IE, Firefox, Safari)" name="external" tool_tip="Standard Webbrowser des Systems verwenden, um die Hilfe, Weblinks usw. anzuzeigen. Bei Vollbildmodus nicht empfohlen." value="true"/>
<radio_item label="Integrierten Browser verwenden" name="internal" tool_tip="Integrierten Webbrowser verwenden, um die Hilfe, Weblinks usw. anzuzeigen. Dieser Browser öffnet als neues Fenster innerhalb von [APP_NAME]." value=""/>
</radio_group>
<check_box initial_value="true" label="Plugins aktivieren" name="browser_plugins_enabled"/>
diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml
new file mode 100644
index 0000000000..10827ce6f2
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_inventory">
+ <text name="title">
+ In meinem Inventar speichern
+ </text>
+ <text name="hint_lbl">
+ Das Speichern eines Bilds in Ihrem Inventar kostet [UPLOAD_COST] L$. Um das Bild als Textur zu speichern, wählen Sie eines der quadratischen Formate aus.
+ </text>
+ <combo_box label="Auflösung" name="texture_size_combo">
+ <combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
+ <combo_box.item label="Klein (128x128)" name="Small(128x128)"/>
+ <combo_box.item label="Mittel (256x256)" name="Medium(256x256)"/>
+ <combo_box.item label="Groß (512x512)" name="Large(512x512)"/>
+ <combo_box.item label="Benutzerdefiniert" name="Custom"/>
+ </combo_box>
+ <spinner label="Breite" name="inventory_snapshot_width"/>
+ <spinner label="Höhe" name="inventory_snapshot_height"/>
+ <check_box label="Seitenverhältnis beibehalten" name="inventory_keep_aspect_check"/>
+ <button label="Abbrechen" name="cancel_btn"/>
+ <button label="Speichern" name="save_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_local.xml b/indra/newview/skins/default/xui/de/panel_snapshot_local.xml
new file mode 100644
index 0000000000..3aeae80388
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_snapshot_local.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_local">
+ <text name="title">
+ Auf meinem Computer speichern
+ </text>
+ <combo_box label="Auflösung" name="local_size_combo">
+ <combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
+ <combo_box.item label="320x240" name="320x240"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="1280x1024" name="1280x1024"/>
+ <combo_box.item label="1600x1200" name="1600x1200"/>
+ <combo_box.item label="Benutzerdefiniert" name="Custom"/>
+ </combo_box>
+ <layout_stack name="local_image_params_ls">
+ <layout_panel name="local_image_size_lp">
+ <spinner label="Breite" name="local_snapshot_width"/>
+ <spinner label="Höhe" name="local_snapshot_height"/>
+ <check_box label="Seitenverhältnis beibehalten" name="local_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="local_image_format_quality_lp">
+ <combo_box label="Format" name="local_format_combo">
+ <combo_box.item label="PNG (verlustfrei)" name="PNG"/>
+ <combo_box.item label="JPEG" name="JPEG"/>
+ <combo_box.item label="BMP (verlustfrei)" name="BMP"/>
+ </combo_box>
+ <slider label="Bildqualität" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <button label="Abbrechen" name="cancel_btn"/>
+ <flyout_button label="Speichern" name="save_btn" tool_tip="Bild als Datei speichern">
+ <flyout_button.item label="Speichern" name="save_item"/>
+ <flyout_button.item label="Speichern unter..." name="saveas_item"/>
+ </flyout_button>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_options.xml b/indra/newview/skins/default/xui/de/panel_snapshot_options.xml
new file mode 100644
index 0000000000..e1d8a5dc6d
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_snapshot_options.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_options">
+ <button label="In meinem Profil posten" name="save_to_profile_btn"/>
+ <button label="E-Mail" name="save_to_email_btn"/>
+ <button label="In meinem Inventar speichern ([AMOUNT] L$)" name="save_to_inventory_btn"/>
+ <button label="Auf meinem Computer speichern" name="save_to_computer_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml
new file mode 100644
index 0000000000..c9afe86d7f
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_postcard">
+ <string name="default_subject">
+ Postkarte aus [SECOND_LIFE].
+ </string>
+ <string name="default_message">
+ Sehen Sie mal!
+ </string>
+ <string name="upload_message">
+ Senden...
+ </string>
+ <text name="title">
+ E-Mail
+ </text>
+ <button label="Nachricht" name="message_btn"/>
+ <button label="Einstellungen" name="settings_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/de/panel_snapshot_profile.xml
new file mode 100644
index 0000000000..8d1c52dea8
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_snapshot_profile.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_profile">
+ <text name="title">
+ In meinem Profil posten
+ </text>
+ <combo_box label="Auflösung" name="profile_size_combo">
+ <combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Benutzerdefiniert" name="Custom"/>
+ </combo_box>
+ <layout_stack name="profile_image_params_ls">
+ <layout_panel name="profile_image_size_lp">
+ <spinner label="Breite" name="profile_snapshot_width"/>
+ <spinner label="Höhe" name="profile_snapshot_height"/>
+ <check_box label="Seitenverhältnis beibehalten" name="profile_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="profile_image_metadata_lp">
+ <text name="caption_label">
+ Bildunterschrift:
+ </text>
+ <check_box initial_value="true" label="Ort einschließen" name="add_location_cb"/>
+ </layout_panel>
+ </layout_stack>
+ <button label="Abbrechen" name="cancel_btn"/>
+ <button label="Posten" name="post_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_status_bar.xml b/indra/newview/skins/default/xui/de/panel_status_bar.xml
index d34fcf70bc..2493d60df6 100644
--- a/indra/newview/skins/default/xui/de/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_status_bar.xml
@@ -18,7 +18,7 @@
<panel name="balance_bg">
<text name="balance" tool_tip="Klicken, um L$-Guthaben zu aktualisieren" value="20 L$"/>
<button label="L$ kaufen" name="buyL" tool_tip="Hier klicken, um mehr L$ zu kaufen"/>
- <button label="Einkaufen" name="goShop" tool_tip="Second Life-Marktplatz öffnen"/>
+ <button label="Einkaufen" name="goShop" tool_tip="Second Life-Marktplatz öffnen" width="85"/>
</panel>
<text name="TimeText" tool_tip="Aktuelle Zeit (Pazifik)">
24:00 H PST
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index 2929556d43..14e9fcdb7f 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -1214,7 +1214,7 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
Sie haben keine Kopie dieser Textur in Ihrem Inventar.
</string>
<string name="InventoryInboxNoItems">
- Objekte, die auf dem Marktplatz gekauft wurden, werden hierher geliefert.
+ Wenn Sie einen Artikel kaufen oder anderweitig erhalten, erscheint er hier, damit Sie ihn in einen Ordner in Ihrem Inventar ziehen bzw. löschen können, wenn Sie ihn nicht behalten möchten.
</string>
<string name="MarketplaceURL">
http://marketplace.[DOMAIN_NAME]
@@ -1412,6 +1412,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="no_attachments">
Keine Anhänge getragen
</string>
+ <string name="Attachments remain">
+ Anhänge (noch [COUNT] Positionen frei)
+ </string>
<string name="Buy">
Kaufen
</string>
@@ -1538,6 +1541,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="Right Pec">
Rechts
</string>
+ <string name="Neck">
+ Hals
+ </string>
+ <string name="Avatar Center">
+ Avatar-Mitte
+ </string>
<string name="Invalid Attachment">
Ungültige Stelle für Anhang
</string>
@@ -4030,6 +4039,18 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
<string name="you_paid_ldollars_no_name">
Sie haben [REASON] [AMOUNT] L$ bezahlt.
</string>
+ <string name="you_paid_failure_ldollars">
+ Sie haben [NAME] [AMOUNT] L$ [REASON] nicht bezahlt.
+ </string>
+ <string name="you_paid_failure_ldollars_no_info">
+ Sie haben [AMOUNT] L$ nicht bezahlt.
+ </string>
+ <string name="you_paid_failure_ldollars_no_reason">
+ Sie haben [NAME] [AMOUNT] L$ nicht bezahlt.
+ </string>
+ <string name="you_paid_failure_ldollars_no_name">
+ Sie haben [AMOUNT] L$ [REASON] nicht bezahlt.
+ </string>
<string name="for item">
für [ITEM]
</string>
@@ -4440,6 +4461,12 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="ExternalEditorFailedToRun">
Externer Editor konnte nicht ausgeführt werden.
</string>
+ <string name="TranslationFailed">
+ Übersetzung fehlgeschlagen: [REASON]
+ </string>
+ <string name="TranslationResponseParseError">
+ Fehler beim Parsen der Übersetzungsantwort.
+ </string>
<string name="Esc">
Esc
</string>
@@ -4810,7 +4837,7 @@ Setzen Sie den Editorpfad in Anführungszeichen
Minikarte
</string>
<string name="Command_Move_Label">
- Bewegen
+ Gehen / Rennen / Fliegen
</string>
<string name="Command_People_Label">
Leute
@@ -4837,10 +4864,10 @@ Setzen Sie den Editorpfad in Anführungszeichen
Sprechen
</string>
<string name="Command_View_Label">
- Ansicht
+ Kamerasteuerungen
</string>
<string name="Command_Voice_Label">
- Stimme in der Nähe
+ Voice-Einstellungen
</string>
<string name="Command_AboutLand_Tooltip">
Informationen zu dem von Ihnen besuchten Land
@@ -4912,7 +4939,16 @@ Setzen Sie den Editorpfad in Anführungszeichen
Kamerawinkel ändern
</string>
<string name="Command_Voice_Tooltip">
- Leute in der Nähe mit Sprechfähigkeit
+ Lautstärkeregler für Anrufe und Leute in Ihrer Nähe in SL
+ </string>
+ <string name="Toolbar_Bottom_Tooltip">
+ gegenwärtig in der unteren Symbolleiste
+ </string>
+ <string name="Toolbar_Left_Tooltip">
+ gegenwärtig in der linken Symbolleiste
+ </string>
+ <string name="Toolbar_Right_Tooltip">
+ gegenwärtig in der rechten Symbolleiste
</string>
<string name="Retain%">
% zurückbehalten
@@ -4938,4 +4974,19 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="Normal">
Normal
</string>
+ <string name="snapshot_quality_very_low">
+ Sehr niedrig
+ </string>
+ <string name="snapshot_quality_low">
+ Niedrig
+ </string>
+ <string name="snapshot_quality_medium">
+ Mittel
+ </string>
+ <string name="snapshot_quality_high">
+ Hoch
+ </string>
+ <string name="snapshot_quality_very_high">
+ Sehr hoch
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/de/teleport_strings.xml b/indra/newview/skins/default/xui/de/teleport_strings.xml
index bbfc830688..9cf381bacc 100644
--- a/indra/newview/skins/default/xui/de/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/de/teleport_strings.xml
@@ -21,8 +21,8 @@ Wenn der Teleport dann immer noch nicht funktioniert, melden Sie sich bitte ab u
Versuchen Sie es später noch einmal.
</message>
<message name="NoHelpIslandTP">
- Sie können nicht zurück nach Welcome Island teleportieren.
-Gehen Sie zu „Welcome Island Public“ und wiederholen sie das Tutorial.
+ Sie können nicht zurück nach Welcome Island teleportieren.
+Gehen Sie zu „Welcome Island Public“, um das Tutorial zu wiederholen.
</message>
<message name="noaccess_tport">
Sie haben leider keinen Zugang zu diesem Teleport-Ziel.
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 4772f744ea..1d5a6740b7 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1206,10 +1206,6 @@ Only large parcels can be listed in search.
name="push_restrict_region_text">
No Pushing (Region Override)
</panel.string>
- <panel.string
- name="see_avs_text">
- Avatars on other parcels can see
- </panel.string>
<text
type="string"
length="1"
@@ -1524,24 +1520,24 @@ Only large parcels can be listed in search.
length="1"
follows="left|top"
text_color="LtGray"
- height="16"
+ height="32"
layout="topleft"
left="274"
- top="166"
+ top="150"
name="allow_label5"
- width="278">
- and chat with avatars on this parcel
+ width="205"
+ wrap="true">
+ Avatars on other parcels can see and chat with avatars on this parcel
</text>
<check_box
height="16"
- label="See Avatars"
follows="top"
layout="topleft"
left="253"
top="150"
name="SeeAvatarsCheck"
tool_tip="Allows avatars on other parcels to see and chat with avatars on this parcel, and you to see and chat with them."
- width="120" />
+ width="10" />
<text
type="string"
length="1"
@@ -1955,36 +1951,18 @@ Only large parcels can be listed in search.
name="access_estate_defined">
(Defined by the Estate)
</panel.string>
- <panel.string
- name="allow_public_access">
- Allow Public Access ([MATURITY]) (Note: Unchecking this will create ban lines)
- </panel.string>
<panel.string
name="estate_override">
One or more of these options is set at the estate level
</panel.string>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="10"
- name="Limit access to this parcel to:"
- text_color="White"
- top="10"
- width="400">
- Access To This Parcel
- </text>
<check_box
follows="top|left"
height="16"
layout="topleft"
- left_delta="0"
+ left="8"
name="public_access"
- top_pad="5"
- label_text.valign="center"
- label_text.v_pad="-2"
+ label="Allow Public Access (Unchecking this will create ban lines)"
+ top_pad="10"
width="278" />
<text
type="string"
@@ -1994,28 +1972,28 @@ Only large parcels can be listed in search.
layout="topleft"
left_delta="20"
name="Only Allow"
- top="49"
+ top="30"
width="325">
- Restrict Access to Residents verified by:
+ Allow access only to Residents who:
</text>
<check_box
follows="top|left"
height="16"
- label="Payment Information on File [ESTATE_PAYMENT_LIMIT]"
+ label="Have payment Information on File [ESTATE_PAYMENT_LIMIT]"
layout="topleft"
left_delta="0"
name="limit_payment"
- tool_tip="Ban unidentified Residents."
+ tool_tip="Residents must have payment information on file to access this parcel. See the [SUPPORT_SITE] for more information."
top_pad="4"
width="278" />
<check_box
follows="top|left"
height="16"
- label="Age Verification [ESTATE_AGE_LIMIT]"
+ label="Have been age-verified [ESTATE_AGE_LIMIT]"
layout="topleft"
left_delta="0"
name="limit_age_verified"
- tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information."
+ tool_tip="Residents must be age verified to access this parcel. See the [SUPPORT_SITE] for more information."
top_pad="4"
width="278" />
<check_box
@@ -2025,7 +2003,7 @@ Only large parcels can be listed in search.
left="8"
name="GroupCheck"
tool_tip="Set group in the General tab."
- top="109"
+ top="89"
width="278" />
<check_box
enabled="false"
diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
index 8d0cecdac3..63992462b3 100644
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
@@ -9,6 +9,7 @@
single_instance="true"
title="NEARBY CHAT"
save_rect="true"
+ save_visibility="true"
can_close="true"
can_minimize="true"
help_topic="chat_bar"
@@ -30,6 +31,7 @@
<panel width="300"
height="31"
left="0"
+ name="bottom_panel"
bottom="-1"
follows="left|right|bottom"
tab_group="1">
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 d101bca694..cd075abc41 100644
--- a/indra/newview/skins/default/xui/en/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml
@@ -34,7 +34,6 @@
left_delta="0"
top_delta="0"
name="external_controls"
- user_resize="false"
width="620">
<web_browser
trusted_content="true"
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 a2739a8339..ca73883e53 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -16,7 +16,7 @@
min_width="250"
min_height="190">
<layout_stack
- animate="false"
+ animate="true"
default_tab_group="2"
follows="all"
height="320"
@@ -32,8 +32,7 @@
min_width="115"
width="150"
height="320"
- auto_resize="false"
- user_resize="false">
+ auto_resize="false">
<panel
name="panel_im_control_panel"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml
index c3324a6aa4..ce788654aa 100644
--- a/indra/newview/skins/default/xui/en/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml
@@ -37,7 +37,6 @@
min_height="20"
name="nav_controls"
top="400"
- user_resize="false"
width="800">
<button
follows="left|top"
@@ -113,7 +112,6 @@
min_height="20"
name="time_controls"
top_delta="0"
- user_resize="false"
width="800">
<button
follows="left|top"
@@ -171,7 +169,6 @@
min_height="20"
name="parcel_owner_controls"
top_delta="0"
- user_resize="false"
width="540">
<button
enabled="false"
@@ -193,7 +190,6 @@
left_delta="0"
name="external_controls"
top_delta="0"
- user_resize="false"
width="540">
<web_browser
bottom="-30"
diff --git a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
new file mode 100644
index 0000000000..498a9b6ce0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<floater
+ open_positioning="cascading"
+ can_close="true"
+ can_resize="true"
+ height="440"
+ help_topic="floater_merchant_outbox"
+ min_width="300"
+ min_height="200"
+ name="floater_merchant_outbox"
+ save_rect="true"
+ save_visibility="false"
+ reuse_instance="true"
+ title="MERCHANT OUTBOX"
+ width="333">
+ <string name="OutboxFolderCount0"></string>
+ <string name="OutboxFolderCount1">1 folder</string>
+ <string name="OutboxFolderCountN">[NUM] folders</string>
+ <string name="OutboxImporting">Sending folders...</string>
+ <string name="OutboxInitializing">Initializing...</string>
+ <panel
+ follows="all"
+ layout="topleft"
+ left="0"
+ top="0"
+ label=""
+ height="440"
+ width="333">
+ <panel
+ follows="all"
+ left="10"
+ bottom="370"
+ width="313"
+ top="0"
+ bg_opaque_color="InventoryBackgroundColor">
+ <panel
+ name="outbox_inventory_placeholder_panel"
+ follows="all"
+ layout="topleft"
+ top="0"
+ left="0"
+ width="308"
+ height="370"
+ bg_opaque_color="InventoryBackgroundColor">
+ <text
+ name="outbox_inventory_placeholder_title"
+ type="string"
+ follows="top|left|right"
+ layout="topleft"
+ top="10"
+ left="0"
+ width="308"
+ height="25"
+ wrap="true"
+ halign="center"
+ font="SansSerifBold">
+ Loading...
+ </text>
+ <text
+ name="outbox_inventory_placeholder_text"
+ type="string"
+ follows="top|left|right"
+ layout="topleft"
+ top="35"
+ left="0"
+ width="308"
+ height="130"
+ wrap="true"
+ halign="left" />
+ </panel>
+ </panel>
+ <panel
+ follows="bottom|left|right"
+ left="10"
+ bottom="435"
+ width="313"
+ top="370">
+ <panel
+ name="outbox_generic_drag_target"
+ mouse_opaque="false"
+ follows="all"
+ top="5"
+ left="5"
+ width="303"
+ height="25"
+ background_visible="false"
+ bg_alpha_color="EmphasisColor_35"
+ border="true"
+ bevel_style="in"
+ visible="true">
+ <text
+ type="string"
+ follows="all"
+ layout="topleft"
+ top="6"
+ height="20"
+ left="5"
+ width="293"
+ halign="center"
+ font="SansSerifMedium"
+ font_shadow="hard"
+ valign="bottom">
+ Drag items here to create folders
+ </text>
+ </panel>
+ <text
+ name="outbox_folder_count"
+ type="string"
+ follows="all"
+ layout="topleft"
+ top="40"
+ left="5"
+ width="150"
+ height="20"
+ wrap="true"
+ halign="left"
+ valign="bottom"
+ font="SansSerif" />
+ <button
+ label="Send to Marketplace"
+ tool_tip="Push to my Marketplace Storefront"
+ is_toggle="false"
+ name="outbox_import_btn"
+ follows="bottom|right"
+ tab_stop="false"
+ halign="center"
+ top="37"
+ left="160"
+ height="25"
+ width="150"
+ enabled="false" />
+ </panel>
+ <layout_stack name="import_progress_indicator" orientation="vertical" left="0" height="440" top="0" width="333" follows="all" visible="false">
+ <layout_panel />
+ <layout_panel height="45" auto_resize="false">
+ <layout_stack orientation="horizontal" left="0" height="45" top="0" width="333" follows="all">
+ <layout_panel width="0" />
+ <layout_panel width="45" auto_resize="false">
+ <loading_indicator
+ height="45"
+ layout="topleft"
+ left="0"
+ top="0"
+ width="45" />
+ </layout_panel>
+ <layout_panel width="0" />
+ </layout_stack>
+ </layout_panel>
+ <layout_panel />
+ </layout_stack>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml
index 9c0af7d9ba..62b8c5f96e 100644
--- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_wizard.xml
@@ -108,7 +108,7 @@
height="22"
top_pad="15"
width="505"
- name="header_panel"
+ name="choose_file_header_panel"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true"
@@ -117,7 +117,7 @@
width="200"
left="10"
top="3"
- name="header_text"
+ name="choose_file_header_text"
text_color="White"
height="10"
font="SansSerifBig"
@@ -130,7 +130,7 @@
left="15"
height="310"
width="505"
- name="content"
+ name="choose_file_content"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
@@ -287,7 +287,7 @@
<panel
height="22"
top_pad="15"
- name="header_panel"
+ name="optimize_header_panel"
width="505"
bg_opaque_color="DkGray2"
background_visible="true"
@@ -296,7 +296,7 @@
<text
width="200"
left="10"
- name="header_text"
+ name="optimize_header_text"
top="3"
text_color="White"
height="10"
@@ -311,7 +311,7 @@
height="20"
font="SansSerifSmall"
layout="topleft"
- name="description"
+ name="optimize_description"
word_wrap="true"
left_delta="5">
We have optimized the model for performance. Adjust it further if you wish.
@@ -322,7 +322,7 @@
left="15"
height="270"
width="505"
- name="content"
+ name="optimize_content"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
@@ -497,7 +497,7 @@ Higher prim weight</text>
<panel
height="22"
top_pad="15"
- name="header_panel"
+ name="physics_header_panel"
width="505"
bg_opaque_color="DkGray2"
background_visible="true"
@@ -506,7 +506,7 @@ Higher prim weight</text>
<text
width="200"
left="10"
- name="header_text"
+ name="physics_header_text"
top="3"
height="10"
font="SansSerifBig"
@@ -521,7 +521,7 @@ Higher prim weight</text>
height="50"
font="SansSerifSmall"
layout="topleft"
- name="description"
+ name="physics_description"
word_wrap="true"
left_delta="5">
We will create a shape for the outer hull of the model. Adjust the shape's detail level as needed for the intended purpose of your model.
@@ -531,7 +531,7 @@ Higher prim weight</text>
left="15"
height="270"
width="505"
- name="content"
+ name="physics_content"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
@@ -635,7 +635,7 @@ Buildings</text>
<panel
height="22"
top_pad="15"
- name="header_panel"
+ name="review_header_panel"
width="505"
bg_opaque_color="DkGray2"
background_visible="true"
@@ -644,7 +644,7 @@ Buildings</text>
<text
width="200"
left="10"
- name="header_text"
+ name="review_header_text"
text_color="White"
top="3"
height="10"
@@ -658,7 +658,7 @@ Buildings</text>
left="15"
height="310"
width="505"
- name="content"
+ name="review_content"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
@@ -706,7 +706,7 @@ Buildings</text>
<panel
height="22"
top_pad="15"
- name="header_panel"
+ name="upload_header_panel"
width="505"
bg_opaque_color="DkGray2"
background_visible="true"
@@ -715,7 +715,7 @@ Buildings</text>
<text
width="200"
left="10"
- name="header_text"
+ name="upload_header_text"
top="3"
text_color="White"
height="10"
diff --git a/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml
new file mode 100644
index 0000000000..f95f21e63a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ can_close="true"
+ bevel_style="in"
+ height="300"
+ layout="topleft"
+ min_height="40"
+ min_width="420"
+ name="Test Floater"
+ title="LAYOUTSTACK TESTS"
+ width="420">
+ <layout_stack name="test_stack"
+ left="0"
+ top="0"
+ width="100"
+ height="250"
+ follows="left|top|bottom"
+ orientation="vertical">
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="test_stack"
+ left_pad="5"
+ top="0"
+ width="100"
+ height="250"
+ follows="left|top|bottom"
+ orientation="vertical">
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="100"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ visible="false"
+ bg_alpha_color="blue"
+ height="100"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="fixed"
+ auto_resize="false"
+ user_resize="true"
+ height="50"
+ min_height="10"
+ bg_alpha_color="green"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="fixed"
+ auto_resize="false"
+ user_resize="true"
+ height="50"
+ min_height="10"
+ bg_alpha_color="green"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="100"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="100"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="100"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="100"
+ visible="true"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="test_stack"
+ left_pad="5"
+ top="0"
+ width="100"
+ height="250"
+ follows="left|top|bottom"
+ orientation="vertical">
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ height="11"
+ bg_alpha_color="blue"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="fixed"
+ auto_resize="false"
+ user_resize="true"
+ height="50"
+ bg_alpha_color="green"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="test_stack"
+ left_pad="5"
+ top="0"
+ width="100"
+ height="250"
+ follows="left|top|bottom"
+ orientation="vertical">
+ <layout_panel name="fixed"
+ auto_resize="false"
+ user_resize="true"
+ height="50"
+ bg_alpha_color="green"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="fixed"
+ auto_resize="false"
+ user_resize="true"
+ height="50"
+ bg_alpha_color="green"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="fixed"
+ auto_resize="false"
+ user_resize="true"
+ height="50"
+ bg_alpha_color="green"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_toybox.xml b/indra/newview/skins/default/xui/en/floater_toybox.xml
index 493d44a9cf..72e6187a14 100644
--- a/indra/newview/skins/default/xui/en/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/en/floater_toybox.xml
@@ -5,7 +5,7 @@
can_minimize="false"
can_resize="false"
default_tab_group="1"
- height="330"
+ height="375"
help_topic="toybox"
layout="topleft"
legacy_header_height="18"
@@ -46,7 +46,7 @@
Buttons will appear as shown or as icon-only depending on each toolbar's settings.
</text>
<toolbar
- bottom="265"
+ bottom="310"
button_display_mode="icons_with_text"
follows="all"
left="20"
@@ -82,11 +82,11 @@
<panel
bevel_style="none"
border="true"
- bottom="266"
+ bottom="311"
follows="left|bottom|right"
left="20"
right="-20"
- top="266" />
+ top="311" />
<button
follows="left|bottom|right"
height="23"
@@ -95,7 +95,7 @@
layout="topleft"
left="185"
name="btn_clear_all"
- top="285"
+ top="330"
width="130">
<button.commit_callback function="Toybox.ClearAll" />
</button>
@@ -107,7 +107,7 @@
layout="topleft"
left="335"
name="btn_restore_defaults"
- top="285"
+ top="330"
width="130">
<button.commit_callback function="Toybox.RestoreDefaults" />
</button>
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 3921cfcd2c..06d4327293 100644
--- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
@@ -22,6 +22,7 @@ or specifying its path in the "Editor Path" field.</string>
layout="topleft"
left="0"
mouse_opaque="false"
+ default_tab_group="1"
name="main_panel"
right="750"
top="0">
@@ -196,6 +197,7 @@ or specifying its path in the "Editor Path" field.</string>
left="10"
name="name_list"
right="-10"
+ tab_group="1"
search_column="1"
top="80">
<scroll_list.columns
diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
index 6807b01fa3..cea19ec75c 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
@@ -49,7 +49,6 @@
width="263">
<layout_panel
follows="top|left|right"
- user_resize="false"
auto_resize="false"
layout="topleft"
min_height="20"
@@ -89,7 +88,7 @@
visible="true"
width="20" />
</layout_panel>
- <layout_panel name="leave_call_panel" height="26" min_height="26" user_resize="false" auto_resize="false">
+ <layout_panel name="leave_call_panel" height="26" min_height="26" auto_resize="false">
<layout_stack
clip="true"
follows="left|top|right"
@@ -110,7 +109,6 @@
</layout_panel>
<layout_panel
auto_resize="false"
- user_resize="false"
follows="top|right"
height="23"
visible="true"
@@ -133,7 +131,6 @@
top_pad="0"
height="132"
name="callers_panel"
- user_resize="false"
auto_resize="true"
width="280">
<avatar_list
diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml
index 57d1c92acb..cea10adca8 100644
--- a/indra/newview/skins/default/xui/en/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/en/floater_web_content.xml
@@ -31,7 +31,6 @@
min_height="20"
name="nav_controls"
top="400"
- user_resize="false"
width="770">
<button
image_overlay="Arrow_Left_Off"
@@ -160,7 +159,6 @@
left_delta="0"
name="external_controls"
top_delta="0"
- user_resize="false"
auto_resize="true"
width="585">
<web_browser
@@ -173,8 +171,7 @@
</layout_panel>
<layout_panel name="status_bar"
height="23"
- auto_resize="false"
- user_resize="false">
+ auto_resize="false">
<text
type="string"
length="200"
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index b4be17e677..a87027a113 100644
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
@@ -23,7 +23,6 @@
left="0"
top="0"
width="1024"
- user_resize="false"
auto_resize="false"
visible="true">
<view mouse_opaque="false"
@@ -40,7 +39,6 @@
name="nav_bar_container"
tab_stop="false"
width="1024"
- user_resize="false"
visible="false"/>
<layout_panel auto_resize="true"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/menu_edit.xml b/indra/newview/skins/default/xui/en/menu_edit.xml
index fab76c497c..99061e089a 100644
--- a/indra/newview/skins/default/xui/en/menu_edit.xml
+++ b/indra/newview/skins/default/xui/en/menu_edit.xml
@@ -6,6 +6,7 @@
<menu_item_call
label="Undo"
name="Undo"
+ allow_key_repeat="true"
shortcut="control|Z">
<menu_item_call.on_click
function="Edit.Undo" />
@@ -15,6 +16,7 @@
<menu_item_call
label="Redo"
name="Redo"
+ allow_key_repeat="true"
shortcut="control|Y">
<menu_item_call.on_click
function="Edit.Redo" />
@@ -43,6 +45,7 @@
<menu_item_call
label="Paste"
name="Paste"
+ allow_key_repeat="true"
shortcut="control|V">
<menu_item_call.on_click
function="Edit.Paste" />
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
index f818ebe2d7..63e154697b 100644
--- a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
@@ -114,6 +114,15 @@
function="Object.EnableMute" />
</menu_item_call>
<menu_item_call
+ label="Unblock"
+ layout="topleft"
+ name="unblock">
+ <menu_item_call.on_click
+ function="Object.Mute" />
+ <menu_item_call.on_visible
+ function="Object.EnableUnmute" />
+ </menu_item_call>
+ <menu_item_call
label="Zoom In"
layout="topleft"
name="zoom_in">
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index fb85e5278a..ef4a1bc061 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -686,12 +686,12 @@
parameter="copy_to_outbox" />
</menu_item_call>
<menu_item_call
- label="Move to Merchant Outbox"
+ label="Send to Marketplace"
layout="topleft"
- name="Merchant Move">
+ name="Marketplace Send">
<menu_item_call.on_click
function="Inventory.DoToSelected"
- parameter="move_to_outbox" />
+ parameter="send_to_marketplace" />
</menu_item_call>
<menu_item_call
label="--no options--"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index 0f42000ae7..e91f5af3d5 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -3,6 +3,7 @@
layout="topleft"
left="0"
mouse_opaque="false"
+ can_tear_off="true"
name="menu_inventory_add"
visible="false">
<menu
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 8ac1ac9e09..101e104eab 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -174,7 +174,58 @@
function="Advanced.WebContentTest"
parameter="http://google.com"/>
</menu_item_call>
- <menu_item_check
+ <menu
+ create_jump_keys="true"
+ label="Set Logging Level"
+ name="Set Logging Level"
+ tear_off="true">
+ <menu_item_check
+ label="Debug">
+ <menu_item_check.on_check
+ function="Develop.CheckLoggingLevel"
+ parameter="0" />
+ <menu_item_check.on_click
+ function="Develop.SetLoggingLevel"
+ parameter="0" />
+ </menu_item_check>
+ <menu_item_check
+ label="Info">
+ <menu_item_check.on_check
+ function="Develop.CheckLoggingLevel"
+ parameter="1" />
+ <menu_item_check.on_click
+ function="Develop.SetLoggingLevel"
+ parameter="1" />
+ </menu_item_check>
+ <menu_item_check
+ label="Warning">
+ <menu_item_check.on_check
+ function="Develop.CheckLoggingLevel"
+ parameter="2" />
+ <menu_item_check.on_click
+ function="Develop.SetLoggingLevel"
+ parameter="2" />
+ </menu_item_check>
+ <menu_item_check
+ label="Error">
+ <menu_item_check.on_check
+ function="Develop.CheckLoggingLevel"
+ parameter="3" />
+ <menu_item_check.on_click
+ function="Develop.SetLoggingLevel"
+ parameter="3" />
+ </menu_item_check>
+ <menu_item_check
+ label="None">
+ <menu_item_check.on_check
+ function="Develop.CheckLoggingLevel"
+ parameter="4" />
+ <menu_item_check.on_click
+ function="Develop.SetLoggingLevel"
+ parameter="4" />
+ </menu_item_check>
+ </menu>
+ <menu_item_check
label="Show Grid Picker"
name="Show Grid Picker"
visible="false"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 0aa5c72f2a..cd8550b00d 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -118,7 +118,7 @@
</menu_item_call>
<menu_item_call
label="Walk / run / fly..."
- name="Stop Animating My Avatar">
+ name="Walk / run / fly">
<menu_item_call.on_click
function="Floater.ToggleOrBringToFront"
parameter="moveview" />
@@ -144,27 +144,10 @@
</menu_item_call>
</menu>
- <menu_item_call
- label="Request Admin Status"
- name="Request Admin Options"
- shortcut="control|alt|G"
- visible="false">
- <menu_item_call.on_click
- function="Advanced.RequestAdminStatus" />
- </menu_item_call>
- <menu_item_call
- label="Leave Admin Status"
- name="Leave Admin Options"
- shortcut="control|alt|shift|G"
- visible="false">
- <menu_item_call.on_click
- function="Advanced.LeaveAdminStatus" />
- </menu_item_call>
-
<menu_item_separator/>
<menu_item_call
- label="Buy L$"
+ label="Buy L$..."
name="Buy and Sell L$">
<menu_item_call.on_click
function="BuyCurrency" />
@@ -525,7 +508,7 @@
<menu
create_jump_keys="true"
label="Sun"
- name="Environment Settings"
+ name="Sun"
tear_off="true">
<menu_item_call
label="Sunrise"
@@ -1154,6 +1137,7 @@
enabled="false"
label="Undo"
name="Undo"
+ allow_key_repeat="true"
shortcut="control|Z">
<on_click
function="Edit.Undo"
@@ -1165,6 +1149,7 @@
enabled="false"
label="Redo"
name="Redo"
+ allow_key_repeat="true"
shortcut="control|Y">
<on_click
function="Edit.Redo"
@@ -1450,7 +1435,7 @@
tear_off="true">
<menu_item_check
label="Simple"
- name="Simple"
+ name="Rendering Type Simple"
shortcut="control|alt|shift|1">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1461,7 +1446,7 @@
</menu_item_check>
<menu_item_check
label="Alpha"
- name="Alpha"
+ name="Rendering Type Alpha"
shortcut="control|alt|shift|2">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1472,7 +1457,7 @@
</menu_item_check>
<menu_item_check
label="Tree"
- name="Tree"
+ name="Rendering Type Tree"
shortcut="control|alt|shift|3">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1483,7 +1468,7 @@
</menu_item_check>
<menu_item_check
label="Avatars"
- name="Character"
+ name="Rendering Type Character"
shortcut="control|alt|shift|4">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1494,7 +1479,7 @@
</menu_item_check>
<menu_item_check
label="Surface Patch"
- name="Surface Patch"
+ name="Rendering Type Surface Patch"
shortcut="control|alt|shift|5">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1505,7 +1490,7 @@
</menu_item_check>
<menu_item_check
label="Sky"
- name="Sky"
+ name="Rendering Type Sky"
shortcut="control|alt|shift|6">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1516,7 +1501,7 @@
</menu_item_check>
<menu_item_check
label="Water"
- name="Water"
+ name="Rendering Type Water"
shortcut="control|alt|shift|7">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1527,7 +1512,7 @@
</menu_item_check>
<menu_item_check
label="Ground"
- name="Ground"
+ name="Rendering Type Ground"
shortcut="control|alt|shift|8">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1538,7 +1523,7 @@
</menu_item_check>
<menu_item_check
label="Volume"
- name="Volume"
+ name="Rendering Type Volume"
shortcut="control|alt|shift|9">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1549,7 +1534,7 @@
</menu_item_check>
<menu_item_check
label="Grass"
- name="Grass"
+ name="Rendering Type Grass"
shortcut="control|alt|shift|0">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1560,7 +1545,7 @@
</menu_item_check>
<menu_item_check
label="Clouds"
- name="Clouds"
+ name="Rendering Type Clouds"
shortcut="control|alt|shift|-">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1571,7 +1556,7 @@
</menu_item_check>
<menu_item_check
label="Particles"
- name="Particles"
+ name="Rendering Type Particles"
shortcut="control|alt|shift|=">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1582,7 +1567,7 @@
</menu_item_check>
<menu_item_check
label="Bump"
- name="Bump"
+ name="Rendering Type Bump"
shortcut="control|alt|shift|\">
<menu_item_check.on_check
function="Advanced.CheckRenderType"
@@ -1599,7 +1584,7 @@
tear_off="true">
<menu_item_check
label="UI"
- name="UI"
+ name="ToggleUI"
shortcut="control|alt|F1">
<menu_item_check.on_check
function="Advanced.CheckFeature"
@@ -1732,28 +1717,6 @@
name="Shortcuts"
tear_off="true"
visible="false">
- <menu_item_call
- label="Image (L$[COST])..."
- name="Upload Image"
- shortcut="control|U">
- <menu_item_call.on_click
- function="File.UploadImage"
- parameter="" />
- <menu_item_call.on_enable
- function="File.EnableUpload" />
- </menu_item_call>
- <menu_item_check
- label="Search"
- name="Search"
- shortcut="control|F">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="search" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="search" />
- </menu_item_check>
-
<!-- This second, alternative shortcut for Show Advanced Menu is for backward compatibility. The main shortcut has been changed so it's Linux-friendly, where the old shortcut is typically eaten by the window manager. -->
<menu_item_check
label="Show Advanced Menu - legacy shortcut"
@@ -1840,55 +1803,6 @@
<menu_item_separator/>
- <menu
- create_jump_keys="true"
- label="Select Build Tool"
- name="Select Tool"
- tear_off="true">
- <menu_item_call
- label="Focus Tool"
- name="Focus"
- shortcut="control|1">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="focus" />
- </menu_item_call>
- <menu_item_call
- label="Move Tool"
- name="Move"
- shortcut="control|2">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="move" />
- </menu_item_call>
- <menu_item_call
- label="Edit Tool"
- name="Edit"
- shortcut="control|3">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="edit" />
- </menu_item_call>
- <menu_item_call
- label="Create Tool"
- name="Create"
- shortcut="control|4">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="create" />
- </menu_item_call>
- <menu_item_call
- label="Land Tool"
- name="Land"
- shortcut="control|5">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="land" />
- </menu_item_call>
- </menu>
-
- <menu_item_separator/>
-
<menu_item_call
label="Zoom In"
name="Zoom In"
@@ -2498,6 +2412,16 @@
function="Advanced.ToggleInfoDisplay"
parameter="rendercomplexity" />
</menu_item_check>
+ <menu_item_check
+ label="Attachment Bytes"
+ name="attachment bytes">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="attachment bytes" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="attachment bytes" />
+ </menu_item_check>
<menu_item_check
label="Sculpt"
name="Sculpt">
@@ -2851,7 +2775,7 @@
<menu
create_jump_keys="true"
label="World"
- name="World"
+ name="DevelopWorld"
tear_off="true">
<menu_item_check
label="Sim Sun Override"
@@ -2864,16 +2788,6 @@
parameter="SkyOverrideSimSunPosition" />
</menu_item_check>
<menu_item_check
- label="Cheesy Beacon"
- name="Cheesy Beacon">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="CheesyBeacon" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="CheesyBeacon" />
- </menu_item_check>
- <menu_item_check
label="Fixed Weather"
name="Fixed Weather">
<menu_item_check.on_check
@@ -3097,7 +3011,7 @@
tear_off="true">
<menu_item_call
label="Iris"
- name="Iris">
+ name="Grab Iris">
<menu_item_call.on_click
function="Advanced.GrabBakedTexture"
parameter="iris" />
@@ -3107,7 +3021,7 @@
</menu_item_call>
<menu_item_call
label="Head"
- name="Head">
+ name="Grab Head">
<menu_item_call.on_click
function="Advanced.GrabBakedTexture"
parameter="head" />
@@ -3117,7 +3031,7 @@
</menu_item_call>
<menu_item_call
label="Upper Body"
- name="Upper Body">
+ name="Grab Upper Body">
<menu_item_call.on_click
function="Advanced.GrabBakedTexture"
parameter="upper" />
@@ -3127,7 +3041,7 @@
</menu_item_call>
<menu_item_call
label="Lower Body"
- name="Lower Body">
+ name="Grab Lower Body">
<menu_item_call.on_click
function="Advanced.GrabBakedTexture"
parameter="lower" />
@@ -3137,7 +3051,7 @@
</menu_item_call>
<menu_item_call
label="Skirt"
- name="Skirt">
+ name="Grab Skirt">
<menu_item_call.on_click
function="Advanced.GrabBakedTexture"
parameter="skirt" />
@@ -3367,6 +3281,57 @@
function="ToggleControl"
parameter="ShowConsoleWindow" />
</menu_item_check>
+ <menu
+ create_jump_keys="true"
+ label="Set Logging Level"
+ name="Set Logging Level"
+ tear_off="true">
+ <menu_item_check
+ label="Debug">
+ <menu_item_check.on_check
+ function="Develop.CheckLoggingLevel"
+ parameter="0" />
+ <menu_item_check.on_click
+ function="Develop.SetLoggingLevel"
+ parameter="0" />
+ </menu_item_check>
+ <menu_item_check
+ label="Info">
+ <menu_item_check.on_check
+ function="Develop.CheckLoggingLevel"
+ parameter="1" />
+ <menu_item_check.on_click
+ function="Develop.SetLoggingLevel"
+ parameter="1" />
+ </menu_item_check>
+ <menu_item_check
+ label="Warning">
+ <menu_item_check.on_check
+ function="Develop.CheckLoggingLevel"
+ parameter="2" />
+ <menu_item_check.on_click
+ function="Develop.SetLoggingLevel"
+ parameter="2" />
+ </menu_item_check>
+ <menu_item_check
+ label="Error">
+ <menu_item_check.on_check
+ function="Develop.CheckLoggingLevel"
+ parameter="3" />
+ <menu_item_check.on_click
+ function="Develop.SetLoggingLevel"
+ parameter="3" />
+ </menu_item_check>
+ <menu_item_check
+ label="None">
+ <menu_item_check.on_check
+ function="Develop.CheckLoggingLevel"
+ parameter="4" />
+ <menu_item_check.on_click
+ function="Develop.SetLoggingLevel"
+ parameter="4" />
+ </menu_item_check>
+ </menu>
<menu_item_separator/>
@@ -3405,10 +3370,11 @@
<menu
create_jump_keys="true"
label="Object"
+ name="AdminObject"
tear_off="true">
<menu_item_call
label="Take Copy"
- name="Take Copy"
+ name="Admin Take Copy"
shortcut="control|alt|shift|O">
<menu_item_call.on_click
function="Admin.ForceTakeCopy" />
@@ -3677,7 +3643,7 @@
<menu
create_jump_keys="true"
label="Help"
- name="Help"
+ name="DeprecatedHelp"
tear_off="true">
<menu_item_call
label="Official Linden Blog"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a7705c8bac..af75d49353 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -203,34 +203,80 @@ Save changes to current clothing/body part?
icon="alertmodal.tga"
name="ConfirmNoCopyToOutbox"
type="alertmodal">
- You don't have permission to copy this item to the Marketplace Outbox. Are you sure you want to move the following item?
- [ITEM_NAME]
+You don't have permission to copy one or more of these items to the Merchant Outbox. You can move them or leave them behind.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Don't move item(s)"
+ yestext="Move item(s)"/>
+ </notification>
+
+ <notification
+ icon="OutboxStatus_Success"
+ name="OutboxFolderCreated"
+ type="outbox">
+ <unique/>
+A new folder has been created for each item you have transferred into the top level of your Merchant Outbox.
+
+ <usetemplate
+ ignoretext="A new folder was created in the Merchant Outbox"
+ name="okignore"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="OutboxStatus_Success"
+ name="OutboxImportComplete"
+ type="outbox">
+Success
+
+All folders were successfully sent to the Marketplace.
+
<usetemplate
- name="okcancelbuttons"
- notext="No"
- yestext="Yes"/>
- </notification>
+ ignoretext="All folders sent to the Marketplace"
+ name="okignore"
+ yestext="OK"/>
+ </notification>
<notification
- icon="alertmodal.tga"
- name="OutboxUploadComplete"
- type="alertmodal">
-Marketplace upload complete.
+ icon="OutboxStatus_Warning"
+ name="OutboxImportHadErrors"
+ type="outbox">
+Some folders did not transfer
+
+Errors occurred when some folders were sent to the Marketplace. Those folders are still in your Merchant Outbox.
+
+See the [[MARKETPLACE_IMPORTS_URL] error log] for more information.
+
<usetemplate
name="okbutton"
- yestext="Hooray!"/>
+ yestext="OK"/>
</notification>
<notification
- icon="alertmodal.tga"
- name="OutboxUploadHadErrors"
- type="alertmodal">
-Marketplace upload completed with errors! Please correct the problems in your outbox and retry. Thanks.
+ icon="OutboxStatus_Error"
+ name="OutboxImportFailed"
+ type="outbox">
+Transfer failed
+
+No folders were sent to the Marketplace because of a system or network error. Try again later.
+
<usetemplate
name="okbutton"
- yestext="Boo!"/>
+ yestext="OK"/>
</notification>
+ <notification
+ icon="OutboxStatus_Error"
+ name="OutboxInitFailed"
+ type="outbox">
+Marketplace initialization failed
+
+Initialization with the Marketplace failed because of a system or network error. Try again later.
+
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
<notification
@@ -3409,7 +3455,7 @@ Are you sure you want to return the selected objects to their owners? Transferab
icon="alert.tga"
name="GroupLeaveConfirmMember"
type="alert">
-You are currently a member of the group [GROUP].
+You are currently a member of the group &lt;nolink&gt;[GROUP]&lt;/nolink&gt;.
Leave Group?
<tag>group</tag>
<tag>confirm</tag>
@@ -6953,6 +6999,26 @@ With the following Residents:
<notification
icon="notifytip.tga"
+ name="ShareFolderConfirmation"
+ type="alertmodal">
+Only one folder at a time can be shared.
+
+Are you sure you want to share the following items:
+
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
+
+With the following Residents:
+
+[RESIDENTS]
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Ok"/>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
name="ItemsShared"
type="notifytip">
Items successfully shared.
diff --git a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
index 93cafd4a53..d68fa6ca6c 100644
--- a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
@@ -27,8 +27,7 @@
mouse_opaque="false"
width="147"
top="0"
- name="speakers_list_panel"
- user_resize="false">
+ name="speakers_list_panel">
<avatar_list
color="DkGray2"
follows="all"
@@ -50,7 +49,6 @@
min_height="25"
width="130"
name="call_btn_panel"
- user_resize="false"
visible="false">
<button
follows="all"
@@ -68,7 +66,6 @@
min_height="25"
width="130"
name="end_call_btn_panel"
- user_resize="false"
visible="false">
<button
follows="all"
@@ -85,7 +82,6 @@
min_height="25"
width="130"
name="voice_ctrls_btn_panel"
- user_resize="false"
visible="false">
<button
follows="all"
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
index b5e1a5f16d..f4722b05d6 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
@@ -31,7 +31,6 @@
width="1000">
<layout_panel
auto_resize="false"
- user_resize="false"
min_width="2"
width="2" />
<layout_panel
@@ -40,8 +39,7 @@
height="28"
layout="topleft"
width="310"
- min_width="188"
- user_resize="false">
+ min_width="188">
<panel
left="0"
filename="panel_nearby_chat_bar.xml"
@@ -61,8 +59,7 @@
width="82"
top_delta="0"
min_width="52"
- name="gesture_panel"
- user_resize="false">
+ name="gesture_panel">
<gesture_combo_list
follows="left|right"
height="23"
@@ -80,7 +77,6 @@
</layout_panel>
<layout_panel
auto_resize="false"
- user_resize="false"
min_width="3"
name="after_gesture_panel"
width="3"/>
diff --git a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
index 41d1036a4d..ff0146490b 100644
--- a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
@@ -27,8 +27,8 @@
min_width="95"
mouse_opaque="false"
name="chiclet_list_panel"
+ auto_resize="true"
top="0"
- user_resize="false"
width="189">
<chiclet_panel
chiclet_padding="4"
@@ -78,7 +78,6 @@
</chiclet_panel>
</layout_panel>
<layout_panel auto_resize="false"
- user_resize="false"
width="4"
min_width="4"/>
<layout_panel
@@ -90,7 +89,6 @@
min_width="37"
name="im_well_panel"
top="0"
- user_resize="false"
width="37">
<chiclet_im_well
follows="right"
@@ -139,7 +137,6 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well
min_width="37"
name="notification_well_panel"
top="0"
- user_resize="false"
width="37">
<chiclet_notification
follows="right"
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index 6c8d994bc6..d4a2745d1d 100644
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -289,8 +289,7 @@
left="0"
top="0"
width="290"
- height="16"
- user_resize="false">
+ height="16">
<text
follows="left|top"
font.style="BOLD"
@@ -327,8 +326,7 @@
left="0"
top="0"
width="290"
- height="16"
- user_resize="false">
+ height="16">
<text
follows="left|top"
font.style="BOLD"
@@ -357,8 +355,7 @@
left="0"
top="0"
width="290"
- height="215"
- user_resize="false">
+ height="215">
<text
auto_resize="false"
follows="left|top"
@@ -416,7 +413,6 @@
layout="bottomleft"
left="0"
name="layout_panel1"
- user_resize="false"
auto_resize="true"
width="101">
<button
@@ -436,7 +432,6 @@
layout="bottomleft"
left_pad="3"
name="show_on_map_btn_lp"
- user_resize="false"
auto_resize="true"
width="100">
<button
@@ -455,7 +450,6 @@
layout="bottomleft"
left_pad="3"
name="edit_btn_lp"
- user_resize="false"
auto_resize="true"
width="101">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
index e512d63f9e..3509eaa285 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
@@ -319,7 +319,6 @@
layout="bottomleft"
left="0"
name="save_changes_btn_lp"
- user_resize="false"
auto_resize="true"
width="156">
<button
@@ -339,7 +338,6 @@
layout="bottomleft"
left_pad="3"
name="show_on_map_btn_lp"
- user_resize="false"
auto_resize="true"
width="157">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index 2ec2e03e8c..0faa1598b1 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -201,7 +201,6 @@
layout="topleft"
left="0"
name="layout_panel1"
- user_resize="false"
auto_resize="true"
width="150">
<button
@@ -221,7 +220,6 @@
layout="topleft"
left_pad="4"
name="layout_panel2"
- user_resize="false"
auto_resize="true"
width="146">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
index 442eb8c28d..2c7c8133d1 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
@@ -435,7 +435,6 @@
layout="bottomleft"
name="save_changes_btn_lp"
top="0"
- user_resize="false"
auto_resize="true"
width="153">
<button
@@ -456,7 +455,6 @@
left_pad="3"
name="show_on_map_btn_lp"
top="0"
- user_resize="false"
auto_resize="true"
width="154">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
index c8764a6a84..69a692e2c4 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
@@ -454,7 +454,6 @@
left="0"
mouse_opaque="false"
name="save_as_btn_lp"
- user_resize="false"
auto_resize="true"
width="154">
<button
@@ -474,7 +473,6 @@
left_pad="3"
mouse_opaque="false"
name="revert_btn_lp"
- user_resize="false"
auto_resize="true"
width="152">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
index c1dc2aaaf7..ad10e53a4e 100644
--- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
@@ -26,8 +26,7 @@
mouse_opaque="false"
width="145"
top="0"
- name="speakers_list_panel"
- user_resize="false">
+ name="speakers_list_panel">
<avatar_list
color="DkGray2"
follows="all"
@@ -48,8 +47,7 @@
layout="topleft"
min_height="28"
width="130"
- name="group_info_btn_panel"
- user_resize="false">
+ name="group_info_btn_panel">
<button
follows="left|right|bottom"
height="23"
@@ -66,8 +64,7 @@
layout="topleft"
min_height="28"
width="130"
- name="call_btn_panel"
- user_resize="false">
+ name="call_btn_panel">
<button
follows="all"
height="23"
@@ -84,7 +81,6 @@
min_height="28"
width="130"
name="end_call_btn_panel"
- user_resize="false"
visible="false">
<button
follows="all"
@@ -101,7 +97,6 @@
min_height="28"
width="130"
name="voice_ctrls_btn_panel"
- user_resize="false"
visible="false">
<button
follows="all"
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 ec3f3b48bc..206496cc0e 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
@@ -97,6 +97,7 @@ background_visible="true"
follows="all"
layout="topleft"
auto_resize="true"
+ user_resize="true"
height="513"
width="313">
<accordion
@@ -195,7 +196,6 @@ background_visible="true"
layout="bottomleft"
left="0"
name="btn_refresh_lp"
- user_resize="false"
auto_resize="false"
width="24">
<button
@@ -215,7 +215,6 @@ background_visible="true"
layout="bottomleft"
left_pad="3"
name="btn_chat_lp"
- user_resize="false"
auto_resize="true"
width="91">
<button
@@ -234,7 +233,6 @@ background_visible="true"
layout="bottomleft"
left_pad="3"
name="call_btn_lp"
- user_resize="false"
auto_resize="true"
width="91">
<button
@@ -255,7 +253,6 @@ background_visible="true"
layout="bottomleft"
left_pad="3"
name="btn_apply_lp"
- user_resize="false"
auto_resize="true"
width="91">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
index 9f73b7c540..8fcd6ccbaf 100644
--- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
@@ -32,8 +32,7 @@
min_height="20"
width="140"
name="view_profile_btn_panel"
- top="0"
- user_resize="false">
+ top="0" >
<button
follows="left|top|right"
height="23"
@@ -49,8 +48,7 @@
layout="topleft"
min_height="25"
width="140"
- name="add_friend_btn_panel"
- user_resize="false">
+ name="add_friend_btn_panel">
<button
follows="left|top|right"
height="23"
@@ -66,8 +64,7 @@
layout="topleft"
min_height="25"
width="140"
- name="teleport_btn_panel"
- user_resize="false">
+ name="teleport_btn_panel">
<button
auto_resize="false"
follows="left|top|right"
@@ -84,8 +81,7 @@
layout="topleft"
min_height="25"
width="140"
- name="share_btn_panel"
- user_resize="false">
+ name="share_btn_panel">
<button
auto_resize="true"
follows="left|top|right"
@@ -101,8 +97,7 @@
layout="topleft"
min_height="25"
width="140"
- name="pay_btn_panel"
- user_resize="false">
+ name="pay_btn_panel">
<button
auto_resize="true"
follows="left|top|right"
@@ -118,8 +113,7 @@
layout="topleft"
min_height="25"
width="140"
- name="call_btn_panel"
- user_resize="false">
+ name="call_btn_panel">
<button
follows="left|top|right"
height="23"
@@ -135,7 +129,6 @@
min_height="25"
width="140"
name="end_call_btn_panel"
- user_resize="false"
visible="false">
<button
follows="left|top|right"
@@ -152,7 +145,6 @@
min_height="25"
width="140"
name="voice_ctrls_btn_panel"
- user_resize="false"
visible="false">
<button
follows="left|top|right"
@@ -169,7 +161,6 @@
layout="topleft"
min_height="0"
width="140"
- name="spacer"
- user_resize="false" />
+ name="spacer"/>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index 23d8cb11ca..2a5933e3e9 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -114,7 +114,6 @@
height="25"
layout="topleft"
name="options_gear_btn_panel"
- user_resize="false"
width="32">
<menu_button
follows="bottom|left"
@@ -135,7 +134,6 @@
height="25"
layout="topleft"
name="add_btn_panel"
- user_resize="false"
width="32">
<button
follows="bottom|left"
@@ -156,7 +154,6 @@
height="25"
layout="topleft"
name="dummy_panel"
- user_resize="false"
width="212">
<icon
follows="bottom|left|right"
@@ -173,7 +170,6 @@
height="25"
layout="topleft"
name="trash_btn_panel"
- user_resize="false"
width="31">
<dnd_button
follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index 6521bf2a4e..223326dd06 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -48,7 +48,6 @@ name="login"
layout="topleft"
width="705"
min_width="705"
-user_resize="false"
height="80">
<text
follows="left|bottom"
@@ -165,7 +164,6 @@ follows="right|bottom"
name="links"
width="205"
min_width="205"
-user_resize="false"
height="80">
<text
follows="right|bottom"
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index e6c5110999..d6d8b2a83e 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- background_visible="true"
default_tab_group="1"
follows="all"
height="423"
@@ -51,10 +50,6 @@
top="18"
width="303" />
<tab_container
- bg_alpha_color="DkGray"
- bg_opaque_color="DkGray"
- background_visible="true"
- background_opaque="true"
follows="all"
halign="center"
height="339"
@@ -71,7 +66,6 @@
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
- background_opaque="true"
border="false"
bevel_style="none"
follows="all"
@@ -90,7 +84,6 @@
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
- background_opaque="true"
border="false"
bevel_style="none"
follows="all"
@@ -119,7 +112,6 @@
height="25"
layout="topleft"
name="options_gear_btn_panel"
- user_resize="false"
width="32">
<menu_button
follows="bottom|left"
@@ -140,7 +132,6 @@
height="25"
layout="topleft"
name="add_btn_panel"
- user_resize="false"
width="32">
<button
follows="bottom|left"
@@ -161,7 +152,6 @@
height="25"
layout="topleft"
name="dummy_panel"
- user_resize="false"
width="212">
<icon
follows="bottom|left|right"
@@ -178,7 +168,6 @@
height="25"
layout="topleft"
name="trash_btn_panel"
- user_resize="false"
width="31">
<dnd_button
follows="bottom|left"
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 7a8e872dc9..4bf420b79f 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -54,11 +54,11 @@
width="800"
height="2"/>
<layout_stack
- use_border="true"
- bevel_style="none"
follows="all"
height="34"
layout="topleft"
+ border_size="0"
+ resize_bar_overlap="3"
left="0"
mouse_opaque="false"
name="nvp_stack"
@@ -73,130 +73,130 @@
min_width="480"
name="navigation_layout_panel"
width="480">
- <panel
- background_visible="false"
- follows="left|top|right"
- top="3"
- height="23"
- layout="topleft"
- left="0"
- name="navigation_panel"
- width="480">
- <pull_button
- follows="left|top"
- direction="down"
- height="23"
- image_overlay="Arrow_Left_Off"
- image_bottom_pad="1"
- layout="topleft"
- left="10"
- name="back_btn"
- tool_tip="Go back to previous location"
- top="2"
- width="31" />
- <pull_button
- follows="left|top"
- direction="down"
- height="23"
- image_overlay="Arrow_Right_Off"
- image_bottom_pad="1"
- layout="topleft"
- left_pad="0"
- name="forward_btn"
- tool_tip="Go forward one location"
- top_delta="0"
- width="31" />
- <button
- follows="left|top"
- height="23"
- image_bottom_pad="1"
- image_overlay="Home_Off"
- layout="topleft"
- left_pad="7"
- name="home_btn"
- tool_tip="Teleport to my home location"
- top_delta="0"
- width="32" />
- <location_input
- follows="all"
- halign="right"
- height="23"
- label="Location"
- layout="topleft"
- left_pad="7"
- max_chars="254"
- mouse_opaque="false"
- name="location_combo"
- top_delta="0"
- width="355">
- <combo_list
- mouse_wheel_opaque="true"/>
- </location_input>
- </panel>
- </layout_panel>
-
- <layout_panel
- auto_resize="false"
- layout="topleft"
- max_width="5"
- min_width="5"
- name="nav_bar_resize_handle_panel"
- user_resize="false"
- width="5">
- <icon
- follows="top|right"
- height="25"
- image_name="ChatBarHandle"
- layout="topleft"
- left="-6"
- name="resize_handle"
- top="4"
- width="5" />
- </layout_panel>
-
+ <panel
+ background_visible="false"
+ follows="left|top|right"
+ top="3"
+ height="23"
+ layout="topleft"
+ left="0"
+ name="navigation_panel"
+ width="480">
+ <pull_button
+ follows="left|top"
+ direction="down"
+ height="23"
+ image_overlay="Arrow_Left_Off"
+ image_bottom_pad="1"
+ layout="topleft"
+ left="10"
+ name="back_btn"
+ tool_tip="Go back to previous location"
+ top="2"
+ width="31" />
+ <pull_button
+ follows="left|top"
+ direction="down"
+ height="23"
+ image_overlay="Arrow_Right_Off"
+ image_bottom_pad="1"
+ layout="topleft"
+ left_pad="0"
+ name="forward_btn"
+ tool_tip="Go forward one location"
+ top_delta="0"
+ width="31" />
+ <button
+ follows="left|top"
+ height="23"
+ image_bottom_pad="1"
+ image_overlay="Home_Off"
+ layout="topleft"
+ left_pad="7"
+ name="home_btn"
+ tool_tip="Teleport to my home location"
+ top_delta="0"
+ width="32" />
+ <location_input
+ follows="all"
+ halign="right"
+ height="23"
+ label="Location"
+ layout="topleft"
+ left_pad="7"
+ max_chars="254"
+ mouse_opaque="false"
+ name="location_combo"
+ top_delta="0"
+ width="355">
+ <combo_list
+ mouse_wheel_opaque="true"/>
+ </location_input>
+ </panel>
+ <icon
+ follows="top|right"
+ height="25"
+ image_name="ChatBarHandle"
+ layout="topleft"
+ left="-3"
+ name="resize_handle"
+ top="4"
+ width="5" />
+ </layout_panel>
<layout_panel
follows="top|left"
- layout="topleft"
+ layout="topleft"
auto_resize="true"
user_resize="true"
min_width="315"
name="favorites_layout_panel"
width="315">
- <favorites_bar
- follows="left|right|top"
- font="SansSerifSmall"
- height="20"
- layout="topleft"
- left="0"
- name="favorite"
- image_drag_indication="Accordion_ArrowOpened_Off"
- tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
- width="311">
- <label
- follows="left|top"
- height="15"
- layout="topleft"
- left="10"
- name="favorites_bar_label"
- text_color="LtGray"
- tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
- top="12"
- width="102">
- Favorites Bar
- </label>
- <!-- More button actually is a text box. -->
- <more_button
- follows="left|bottom"
- name=">>"
- tab_stop="false"
- tool_tip="Show more of My Favorites"
- top="13"
- width="50"
- bottom="0"
- valign="bottom">
- More &#9660;
- </more_button>
- </favorites_bar>
+ <icon
+ follows="top|left"
+ height="25"
+ image_name="ChatBarHandle"
+ layout="topleft"
+ left="-318"
+ name="resize_handle"
+ top="4"
+ width="5" />
+
+ <favorites_bar
+ follows="left|right|top"
+ font="SansSerifSmall"
+ height="20"
+ layout="topleft"
+ left="0"
+ top="4"
+ name="favorite"
+ image_drag_indication="Accordion_ArrowOpened_Off"
+ tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
+ width="311">
+ <label
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="favorites_bar_label"
+ text_color="LtGray"
+ tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
+ top="12"
+ width="102">
+ Favorites Bar
+ </label>
+ <!-- More button actually is a text box. -->
+ <more_button
+ follows="left|bottom"
+ name=">>"
+ tab_stop="false"
+ tool_tip="Show more of My Favorites"
+ top="13"
+ width="50"
+ bottom="0"
+ valign="bottom">
+ More &#9660;
+ </more_button>
+ </favorites_bar>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_media.xml b/indra/newview/skins/default/xui/en/panel_nearby_media.xml
index bfc503f05b..d1cb64f7ad 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_media.xml
@@ -196,7 +196,6 @@
name="stop"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="22"
@@ -224,7 +223,6 @@
name="play"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="22"
@@ -252,7 +250,6 @@
name="pause"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
min_width="22"
@@ -279,7 +276,6 @@
name="volume_slider_ctrl"
mouse_opaque="false"
auto_resize="true"
- user_resize="false"
follows="left|right"
layout="topleft"
top="0"
@@ -304,7 +300,6 @@
name="mute"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="72"
@@ -333,7 +328,6 @@
name="zoom"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="28"
@@ -361,7 +355,6 @@
name="unzoom"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
min_width="21"
@@ -388,8 +381,7 @@
<layout_panel
name="right_bookend"
width="0"
- mouse_opaque="false"
- user_resize="false" />
+ mouse_opaque="false"/>
</layout_stack>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
index 66117615e4..a3d39e55af 100644
--- a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
@@ -8,7 +8,6 @@
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
- background_opaque="true"
border="false"
bevel_style="none"
show_item_link_overlays="true"
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index e1cd78bad8..b61f110e32 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -198,7 +198,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap
height="154"
name="add_button_and_combobox"
width="311"
- user_resize="false"
visible="true">
<!-- List containing items from the COF and Base outfit -->
@@ -271,8 +270,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
height="30"
name="filter_panel"
width="311"
- visible="false"
- user_resize="false">
+ visible="false">
<filter_editor
background_image="TextField_Search_Off"
@@ -515,7 +513,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap
left="0"
mouse_opaque="false"
name="save_btn_lp"
- user_resize="false"
auto_resize="true"
width="156">
<button
@@ -550,7 +547,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap
left_pad="3"
mouse_opaque="false"
name="revert_btn_lp"
- user_resize="false"
auto_resize="true"
width="147">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
index 2ad2416179..405d9513db 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -84,7 +84,6 @@
left="0"
mouse_opaque="false"
name="save_btn_lp"
- user_resize="false"
auto_resize="true"
width="156">
<button
@@ -118,7 +117,6 @@
left_pad="3"
mouse_opaque="false"
name="wear_btn_lp"
- user_resize="false"
auto_resize="true"
width="147">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 0ebfd9c037..98c7c49ff4 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -284,7 +284,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
height="25"
layout="topleft"
name="options_gear_btn_panel"
- user_resize="false"
width="32">
<menu_button
follows="bottom|left"
@@ -305,7 +304,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
height="25"
layout="topleft"
name="add_btn_panel"
- user_resize="false"
width="32">
<button
follows="bottom|left"
@@ -326,7 +324,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
height="25"
layout="topleft"
name="dummy_panel"
- user_resize="false"
width="210">
<icon
follows="bottom|left|right"
@@ -343,7 +340,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
height="25"
layout="topleft"
name="trash_btn_panel"
- user_resize="false"
width="31">
<dnd_button
follows="bottom|left"
@@ -602,7 +598,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
layout="bottomleft"
left="0"
name="view_profile_btn_lp"
- user_resize="false"
auto_resize="true"
width="68">
<button
@@ -623,7 +618,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
layout="bottomleft"
left_pad="3"
name="im_btn_lp"
- user_resize="false"
auto_resize="true"
width="41">
<button
@@ -644,7 +638,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
layout="bottomleft"
left_pad="3"
name="call_btn_lp"
- user_resize="false"
auto_resize="true"
width="52">
<button
@@ -665,7 +658,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
layout="bottomleft"
left_pad="3"
name="share_btn_lp"
- user_resize="false"
auto_resize="true"
width="66">
<button
@@ -686,7 +678,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
layout="bottomleft"
left_pad="3"
name="teleport_btn_lp"
- user_resize="false"
auto_resize="true"
width="77">
<button
@@ -720,7 +711,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left="0"
mouse_opaque="false"
name="group_info_btn_lp"
- user_resize="false"
auto_resize="true"
width="108">
<button
@@ -743,7 +733,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left_pad="3"
mouse_opaque="false"
name="chat_btn_lp"
- user_resize="false"
auto_resize="true"
width="101">
<button
@@ -766,7 +755,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left_pad="3"
mouse_opaque="false"
name="group_call_btn_lp"
- user_resize="false"
auto_resize="true"
width="96">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
index 24046d5cca..79d190e1e0 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -139,7 +139,6 @@
layout="bottomleft"
left="0"
name="layout_panel1"
- user_resize="false"
auto_resize="true"
width="101">
<button
@@ -158,7 +157,6 @@
layout="bottomleft"
left_pad="3"
name="show_on_map_btn_lp"
- user_resize="false"
auto_resize="true"
width="100">
<button
@@ -177,7 +175,6 @@
layout="bottomleft"
left_pad="3"
name="edit_btn_lp"
- user_resize="false"
auto_resize="true"
width="101">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index 85f402dfa2..8def96cada 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -102,7 +102,6 @@ bg_opaque_color="DkGray2"
layout="bottomleft"
left="0"
name="gear_menu_btn"
- user_resize="false"
auto_resize="true"
width="51">
<button
@@ -124,7 +123,6 @@ bg_opaque_color="DkGray2"
height="18"
layout="bottomleft"
name="trash_btn_lp"
- user_resize="false"
auto_resize="true"
width="18">
<button
@@ -170,7 +168,6 @@ bg_opaque_color="DkGray2"
layout="topleft"
left="0"
name="info_btn_lp"
- user_resize="false"
auto_resize="true"
top="0"
width="95">
@@ -192,7 +189,6 @@ bg_opaque_color="DkGray2"
layout="bottomleft"
left_pad="2"
name="teleport_btn_lp"
- user_resize="false"
auto_resize="true"
width="117">
<button
@@ -212,7 +208,6 @@ bg_opaque_color="DkGray2"
height="28"
layout="bottomleft"
name="show_on_map_btn_lp"
- user_resize="false"
auto_resize="true"
left_pad="2"
width="90">
diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml
index e280115bda..308acf0c0c 100644
--- a/indra/newview/skins/default/xui/en/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml
@@ -238,7 +238,6 @@
mouse_opaque="false"
name="here_panel"
top="0"
- user_resize="false"
width="60">
<icon
follows="top|left"
@@ -259,7 +258,6 @@
mouse_opaque="false"
name="for_sale_panel"
top="0"
- user_resize="false"
width="60">
<icon
follows="top|left"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index 670aa47313..f169dbb702 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -92,7 +92,6 @@ background_visible="true"
left="0"
mouse_opaque="false"
name="lp1"
- user_resize="false"
auto_resize="true"
width="193">
@@ -115,7 +114,6 @@ background_visible="true"
left="0"
mouse_opaque="false"
name="teleport_btn_lp"
- user_resize="false"
auto_resize="true"
width="109">
<button
@@ -137,7 +135,6 @@ background_visible="true"
left_pad="3"
mouse_opaque="false"
name="chat_btn_lp"
- user_resize="false"
auto_resize="true"
width="86">
<button
@@ -161,7 +158,6 @@ background_visible="true"
left_pad="0"
mouse_opaque="false"
name="lp2"
- user_resize="false"
auto_resize="true"
width="116">
@@ -185,7 +181,6 @@ background_visible="true"
left_pad="0"
mouse_opaque="false"
name="edit_btn_lp"
- user_resize="false"
auto_resize="true"
width="84">
<button
@@ -208,7 +203,6 @@ background_visible="true"
left_pad="0"
mouse_opaque="false"
name="overflow_btn_lp"
- user_resize="false"
auto_resize="true"
width="24">
<menu_button
@@ -246,7 +240,6 @@ background_visible="true"
left_pad="3"
mouse_opaque="false"
name="profile_btn_lp"
- user_resize="false"
auto_resize="true"
width="102">
<button
@@ -283,7 +276,6 @@ background_visible="true"
mouse_opaque="false"
name="close_btn_lp"
top="0"
- user_resize="false"
auto_resize="true"
width="51">
<button
@@ -324,7 +316,6 @@ background_visible="true"
mouse_opaque="false"
name="save_btn_lp"
top="0"
- user_resize="false"
auto_resize="true"
width="153">
<button
@@ -347,7 +338,6 @@ background_visible="true"
mouse_opaque="false"
name="cancel_btn_lp"
top="0"
- user_resize="false"
auto_resize="true"
width="154">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_postcard_settings.xml b/indra/newview/skins/default/xui/en/panel_postcard_settings.xml
index 2e0bb88f53..e9427a2388 100644
--- a/indra/newview/skins/default/xui/en/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/en/panel_postcard_settings.xml
@@ -50,7 +50,6 @@
layout="topleft"
left="0"
name="postcard_image_size_lp"
- user_resize="false"
auto_resize="false"
top="0"
right="-1"
@@ -99,7 +98,6 @@
layout="topleft"
left="0"
name="postcard_image_format_quality_lp"
- user_resize="false"
auto_resize="true"
top="0"
right="-1"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index 4079a80924..9827180aa7 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -420,7 +420,7 @@
follows="left|top"
height="29"
layout="topleft"
- left="50"
+ left="30"
name="busy_response"
width="470"
word_wrap="true">
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index 47236c1a48..587c461bee 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -59,7 +59,6 @@
top_pad="30"
width="350" />
<check_box
- enabled_control="EnableVoiceChat"
control_name="VoiceCallsFriendsOnly"
height="16"
label="Only friends and groups can call or IM me"
diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
index 273c252474..198ccd6e2f 100644
--- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
@@ -31,8 +31,7 @@
width="0"
name="left_bookend_bottom"
mouse_opaque="false"
- layout="topleft"
- user_resize="false" />
+ layout="topleft"/>
<layout_panel
name="media_progress_indicator"
mouse_opaque="false"
@@ -41,7 +40,6 @@
left="0"
top="0"
auto_resize="false"
- user_resize="false"
min_width="100"
width="200">
<progress_bar
@@ -59,8 +57,7 @@
name="right_bookend_bottom"
width="0"
mouse_opaque="false"
- layout="topleft"
- user_resize="false" />
+ layout="topleft"/>
</layout_stack>
<layout_stack
name="media_controls"
@@ -79,13 +76,11 @@
top="0"
width="0"
mouse_opaque="false"
- layout="topleft"
- user_resize="false" />
+ layout="topleft"/>
<layout_panel
name="back"
top="0"
auto_resize="false"
- user_resize="false"
layout="topleft"
mouse_opaque="false"
min_width="22"
@@ -114,7 +109,6 @@
name="fwd"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
min_width="22"
top="0"
@@ -142,7 +136,6 @@
name="home"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="22"
@@ -170,7 +163,6 @@
name="media_stop"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="22"
@@ -198,7 +190,6 @@
name="reload"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="22"
@@ -226,7 +217,6 @@
name="stop"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="22"
@@ -254,7 +244,6 @@
name="play"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="22"
@@ -282,7 +271,6 @@
name="pause"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
min_width="22"
@@ -310,7 +298,6 @@
name="media_address"
mouse_opaque="false"
auto_resize="true"
- user_resize="false"
height="24"
follows="left|right|bottom"
layout="topleft"
@@ -343,8 +330,7 @@
layout="topleft"
width="16"
mouse_opaque="false"
- auto_resize="false"
- user_resize="false">
+ auto_resize="false">
<icon
name="media_whitelist_flag"
follows="top|right"
@@ -358,8 +344,7 @@
layout="topleft"
width="16"
mouse_opaque="false"
- auto_resize="false"
- user_resize="false">
+ auto_resize="false">
<icon
name="media_secure_lock_flag"
height="16"
@@ -374,7 +359,6 @@
name="media_play_position"
mouse_opaque="false"
auto_resize="true"
- user_resize="false"
follows="left|right"
layout="topleft"
top="0"
@@ -399,7 +383,6 @@
name="skip_back"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
min_width="22"
@@ -428,7 +411,6 @@
name="skip_forward"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
min_width="22"
@@ -455,7 +437,6 @@
name="media_volume"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="72"
@@ -511,7 +492,6 @@
name="zoom_frame"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
height="28"
@@ -539,7 +519,6 @@
name="close"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
min_width="21"
@@ -567,7 +546,6 @@
name="new_window"
mouse_opaque="false"
auto_resize="false"
- user_resize="false"
layout="topleft"
top="0"
min_width="22"
@@ -596,8 +574,7 @@
mouse_opaque="false"
top="0"
width="0"
- layout="topleft"
- user_resize="false" />
+ layout="topleft"/>
</layout_stack>
<panel
name="media_region"
diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml
index 4535c56339..860caf2d21 100644
--- a/indra/newview/skins/default/xui/en/panel_progress.xml
+++ b/indra/newview/skins/default/xui/en/panel_progress.xml
@@ -12,45 +12,43 @@
height="768"
layout="topleft"
left="0"
- name="stack1"
+ name="horizontal_centering"
orientation="horizontal"
top="0"
width="1024">
<layout_panel
layout="topleft"
min_width="10"
- name="panel1"
- user_resize="false"
+ name="left"
width="150" />
<layout_panel
height="768"
layout="topleft"
- min_width="640"
- name="panel2"
- user_resize="false"
- width="640">
+ min_width="670"
+ name="center"
+ width="670">
<layout_stack
follows="left|right|top|bottom"
height="768"
layout="topleft"
left="0"
orientation="vertical"
- name="stack2"
+ name="vertical_centering"
top="0"
- width="640">
+ width="670">
<layout_panel
height="200"
layout="topleft"
min_height="10"
name="panel3"
- width="640" />
+ width="670" />
<layout_panel
auto_resize="false"
height="250"
layout="topleft"
min_height="250"
name="panel4"
- width="640">
+ width="670">
<icon
color="LoginProgressBoxCenterColor"
follows="left|right|bottom|top"
@@ -59,7 +57,7 @@
layout="topleft"
left="0"
top="0"
- width="640" />
+ width="670" />
<text
follows="left|right|top"
font="SansSerifHuge"
@@ -71,7 +69,7 @@
name="title_text"
text_color="LoginProgressBoxTextColor"
top_delta="50"
- width="593" />
+ right="-47"/>
<text
follows="left|right|top"
font="SansSerif"
@@ -83,7 +81,7 @@
name="progress_text"
text_color="LoginProgressBoxTextColor"
top_pad="5"
- width="593"
+ right="-47"
word_wrap="true"/>
<progress_bar
bottom="115"
@@ -106,7 +104,7 @@
name="message_text"
text_color="LoginProgressBoxTextColor"
top="145"
- width="550"
+ right="-90"
word_wrap="true"/>
</layout_panel>
<layout_panel
@@ -114,14 +112,13 @@
layout="topleft"
min_width="10"
name="panel5"
- width="640" />
+ width="670" />
</layout_stack>
</layout_panel>
<layout_panel
layout="topleft"
min_width="10"
- name="panel6"
- user_resize="false"
+ name="right"
width="150" />
</layout_stack>
<button
diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml
index 6b28639a77..bfd796a62b 100644
--- a/indra/newview/skins/default/xui/en/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml
@@ -134,26 +134,26 @@
name="Only Allow"
top_delta="-30"
width="278">
- Restrict Access to accounts verified by:
+ Allow access only to Residents who:
</text>
<check_box
follows="top|left"
height="16"
- label="Payment Information on File"
+ label="Have payment information on file"
layout="topleft"
left_delta="0"
name="limit_payment"
- tool_tip="Ban unidentified Residents"
+ tool_tip="Residents must have payment information on file to access this estate. See the [SUPPORT_SITE] for more information."
top_pad="2"
width="278" />
<check_box
follows="top|left"
height="16"
- label="Age Verification"
+ label="Have been age-verified"
layout="topleft"
left_delta="0"
name="limit_age_verified"
- tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information."
+ tool_tip="Residents must be age verified to access this estate. See the [SUPPORT_SITE] for more information."
top_pad="2"
width="278" />
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 8d42024386..f6a8af0973 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -54,12 +54,22 @@
label="Save"
layout="topleft"
name="Save" />
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Revert All Changes"
- layout="topleft"
- name="Revert All Changes" />
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Revert All Changes"
+ layout="topleft"
+ name="Revert All Changes" />
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Load from file..."
+ layout="topleft"
+ name="LoadFromFile" />
+ <menu_item_call
+ label="Save to file..."
+ layout="topleft"
+ name="SaveToFile" />
</menu>
<menu
top="0"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
index ae0215a578..b966358f18 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
@@ -96,7 +96,6 @@
layout="topleft"
left="0"
name="local_image_size_lp"
- user_resize="false"
auto_resize="false"
top="0"
right="-1"
@@ -145,7 +144,6 @@
layout="topleft"
left="0"
name="local_image_format_quality_lp"
- user_resize="false"
auto_resize="true"
top="0"
right="-1"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml
index d8ff043444..ebba292a93 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml
@@ -16,14 +16,6 @@
name="upload_message">
Sending...
</string>
- <string
- name="default_subject">
- Postcard from [SECOND_LIFE].
- </string>
- <string
- name="default_message">
- Check this out!
- </string>
<icon
follows="top|left"
height="18"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
index 91ac9ad658..5bd383b81e 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
@@ -84,7 +84,6 @@
layout="topleft"
left="0"
name="profile_image_size_lp"
- user_resize="false"
auto_resize="false"
top="0"
right="-1"
@@ -132,7 +131,6 @@
layout="topleft"
left="0"
name="profile_image_metadata_lp"
- user_resize="false"
auto_resize="true"
top="0"
right="-1"
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 3239c4e531..d453a970e7 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -70,7 +70,7 @@
pad_bottom="2"
tool_tip="Click to buy more L$"
top="0"
- width="55" />
+ width="80" />
<button
halign="left"
font="SansSerifSmall"
@@ -87,7 +87,6 @@
left_pad="0"
label_shadow="true"
name="goShop"
- pad_right="0"
pad_bottom="2"
tool_tip="Open Second Life Marketplace"
top="0"
diff --git a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
index 3c69a0cb6c..58911bed56 100644
--- a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
@@ -20,7 +20,6 @@
mouse_opaque="false">
<layout_panel name="vertical_toolbar_panel"
auto_resize="true"
- user_resize="false"
width="1024"
height="500"
mouse_opaque="false">
@@ -34,7 +33,6 @@
mouse_opaque="false">
<layout_panel name="left_toolbar_panel"
auto_resize="false"
- user_resize="false"
height="500"
width="30"
mouse_opaque="false">
@@ -61,7 +59,6 @@
</layout_panel>
<layout_panel name="non_toolbar_panel"
auto_resize="true"
- user_resize="false"
mouse_opaque="false"
height="100"
width="200">
@@ -102,7 +99,6 @@
</layout_panel>
<layout_panel name="right_toolbar_panel"
auto_resize="false"
- user_resize="false"
height="500"
width="30"
mouse_opaque="false">
@@ -132,7 +128,6 @@
</layout_panel>
<layout_panel name="bottom_toolbar_panel"
auto_resize="false"
- user_resize="false"
height="30"
width="1024"
mouse_opaque="false">
diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
index b52784d6bc..fcba937bdb 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- background_visible="true"
follows="all"
height="570"
label="Things"
@@ -30,11 +29,12 @@
width="330">
<layout_panel
name="main_inventory_layout_panel"
- layout="topleft"
+ layout="topleft"
+ auto_resize="true"
+ user_resize="true"
min_dim="150"
width="330"
follows="bottom|left|right"
- user_resize="false"
height="300">
<panel
class="panel_main_inventory"
@@ -48,41 +48,18 @@
height="300"
width="330" />
</layout_panel>
- <layout_panel
- width="330"
- layout="topleft"
- auto_resize="true"
- user_resize="false"
- follows="bottom|left|right"
- name="inbox_outbox_layout_panel"
- visible="false"
- min_dim="35"
- max_dim="235"
- expanded_min_dim="125"
- height="235">
- <layout_stack
- follows="left|right|top|bottom"
- layout="topleft"
- left="0"
- top="0"
- orientation="vertical"
- name="inbox_outbox_layout_stack"
- open_time_constant="0.02"
- close_time_constant="0.02"
- height="235"
- width="330">
- <layout_panel
+ <layout_panel
width="330"
- layout="topleft"
+ layout="topleft"
auto_resize="true"
- user_resize="false"
+ user_resize="true"
follows="left|right|top"
name="inbox_layout_panel"
visible="false"
min_dim="35"
- max_dim="200"
+ max_dim="235"
expanded_min_dim="90"
- height="200">
+ height="235">
<panel
follows="all"
layout="topleft"
@@ -91,13 +68,13 @@
class="panel_marketplace_inbox"
top="0"
label=""
- height="200"
+ height="235"
width="330">
<string name="InboxLabelWithArg">Received items ([NUM])</string>
<string name="InboxLabelNoArg">Received items</string>
<button
label="Received items"
- font="SansSerifMedium"
+ font="SansSerifMedium"
name="inbox_btn"
height="35"
width="308"
@@ -129,7 +106,7 @@
<panel
follows="all"
left="10"
- bottom="200"
+ bottom="235"
width="308"
top="35"
bg_opaque_color="InventoryBackgroundColor"
@@ -145,7 +122,7 @@
top="0"
left="0"
width="308"
- height="165"
+ height="200"
wrap="true"
halign="center">
Purchases from the marketplace will be delivered here.
@@ -153,139 +130,6 @@
</panel>
</panel>
</layout_panel>
- <layout_panel
- width="330"
- layout="topleft"
- auto_resize="true"
- user_resize="false"
- follows="all"
- name="outbox_layout_panel"
- visible="false"
- min_dim="35"
- max_dim="200"
- expanded_min_dim="90"
- height="200">
- <panel
- follows="all"
- layout="topleft"
- left="0"
- name="marketplace_outbox"
- class="panel_marketplace_outbox"
- top="0"
- label=""
- height="200"
- width="330">
- <string name="OutboxLabelWithArg">Merchant outbox ([NUM])</string>
- <string name="OutboxLabelNoArg">Merchant outbox</string>
- <button
- label="Merchant outbox"
- font="SansSerifMedium"
- name="outbox_btn"
- height="35"
- width="308"
- image_unselected="MarketplaceBtn_Off"
- image_selected="MarketplaceBtn_Selected"
- halign="left"
- handle_right_mouse="false"
- follows="top|left|right"
- is_toggle="true"
- tab_stop="false"
- pad_left="35"
- top="0"
- left="10" />
- <button
- image_unselected="OutboxPush_Off"
- image_selected="OutboxPush_Selected"
- image_hover_selected="OutboxPush_Selected_Over"
- image_hover_unselected="OutboxPush_Over"
- image_disabled_selected="OutboxPush_Selected_Disabled"
- image_disabled="OutboxPush_Disabled"
- image_pressed="OutboxPush_Press"
- image_pressed_selected="OutboxPush_Selected_Press"
- label=""
- tool_tip="Push to my Marketplace Storefront"
- is_toggle="false"
- name="outbox_sync_btn"
- follows="top|right"
- tab_stop="false"
- halign="center"
- top="6"
- left="-50"
- height="23"
- width="32"
- enabled="false" />
- <loading_indicator
- follows="top|right"
- name="outbox_sync_indicator"
- top="6"
- left="-50"
- height="23"
- width="32"
- images_per_sec="1.15"
- tab_stop="false"
- visible="false">
- <images>
- <image name="OutboxPush_Progress_1"/>
- <image name="OutboxPush_Progress_2"/>
- <image name="OutboxPush_Progress_3"/>
- <image name="OutboxPush_Progress_4"/>
- <image name="OutboxPush_Progress_5"/>
- <image name="OutboxPush_Progress_6"/>
- </images>
- </loading_indicator>
- <panel
- follows="all"
- left="10"
- bottom="200"
- width="308"
- top="35"
- bg_opaque_color="InventoryBackgroundColor"
- background_visible="true"
- background_opaque="true"
- >
- <panel
- name="outbox_inventory_placeholder_panel"
- follows="all"
- layout="topleft"
- top="0"
- left="0"
- width="308"
- height="165"
- bg_opaque_color="InventoryBackgroundColor"
- background_visible="true"
- background_opaque="true"
- >
- <text
- name="outbox_inventory_placeholder_title"
- type="string"
- follows="all"
- layout="topleft"
- top="10"
- left="0"
- width="308"
- height="25"
- wrap="true"
- halign="center"
- font="SansSerifBold">
- Loading...
- </text>
- <text
- name="outbox_inventory_placeholder_text"
- type="string"
- follows="all"
- layout="topleft"
- top="35"
- left="0"
- width="308"
- height="130"
- wrap="true"
- halign="left" />
- </panel>
- </panel>
- </panel>
- </layout_panel>
- </layout_stack>
- </layout_panel>
</layout_stack>
<panel
follows="bottom|left|right"
@@ -312,7 +156,6 @@
left="0"
mouse_opaque="false"
name="info_btn_lp"
- user_resize="false"
auto_resize="true"
width="101">
<button
@@ -334,7 +177,6 @@
left_pad="1"
mouse_opaque="false"
name="share_btn_lp"
- user_resize="false"
auto_resize="true"
width="100">
<button
@@ -356,7 +198,6 @@
left_pad="1"
mouse_opaque="false"
name="shop_btn_lp"
- user_resize="false"
auto_resize="true"
width="100">
<button
@@ -406,8 +247,7 @@
</layout_stack>
</panel>
</panel>
-
-<panel
+ <panel
follows="all"
layout="topleft"
left="0"
@@ -420,8 +260,7 @@
visible="false"
width="330">
</panel>
-
-<panel
+ <panel
follows="all"
layout="topleft"
left="0"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 9752a07b66..3351ffe00f 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -18,7 +18,7 @@
<string name="StartupClearingCache">Clearing cache...</string>
<string name="StartupInitializingTextureCache">Initializing texture cache...</string>
<string name="StartupInitializingVFS">Initializing VFS...</string>
- <string name="StartupRequireDriverUpdate">Graphics initialization failed. Please update your graphics driver!</string>
+ <string name="StartupRequireDriverUpdate">Graphics initialization failed. Please update your graphics driver!</string>
<!-- progress -->
<string name="ProgressRestoring">Restoring...</string>
@@ -35,9 +35,9 @@
<string name="LoginAttempt">Previous login attempt failed. Logging in, attempt [NUMBER]</string>
<string name="LoginPrecaching">Loading world...</string>
<string name="LoginInitializingBrowser">Initializing embedded web browser...</string>
- <string name="LoginInitializingMultimedia">Initializing multimedia...</string>
- <string name="LoginInitializingFonts">Loading fonts...</string>
- <string name="LoginVerifyingCache">Verifying cache files (can take 60-90 seconds)...</string>
+ <string name="LoginInitializingMultimedia">Initializing multimedia...</string>
+ <string name="LoginInitializingFonts">Loading fonts...</string>
+ <string name="LoginVerifyingCache">Verifying cache files (can take 60-90 seconds)...</string>
<string name="LoginProcessingResponse">Processing response...</string>
<string name="LoginInitializingWorld">Initializing world...</string>
<string name="LoginDecodingImages">Decoding images...</string>
@@ -49,12 +49,12 @@
<string name="LoginWaitingForRegionHandshake">Waiting for region handshake...</string>
<string name="LoginConnectingToRegion">Connecting to region...</string>
<string name="LoginDownloadingClothing">Downloading clothing...</string>
- <string name="InvalidCertificate">The server returned an invalid or corrupt certificate. Please contact the Grid administrator.</string>
- <string name="CertInvalidHostname">An invalid hostname was used to access the server, please check your SLURL or Grid hostname.</string>
- <string name="CertExpired">The certificate returned by the Grid appears to be expired. Please check your system clock, or contact your Grid administrator.</string>
- <string name="CertKeyUsage">The certificate returned by the server could not be used for SSL. Please contact your Grid administrator.</string>
- <string name="CertBasicConstraints">Too many certificates were in the servers Certificate chain. Please contact your Grid administrator.</string>
- <string name="CertInvalidSignature">The certificate signature returned by the Grid server could not be verified. Please contact your Grid administrator.</string>
+ <string name="InvalidCertificate">The server returned an invalid or corrupt certificate. Please contact the Grid administrator.</string>
+ <string name="CertInvalidHostname">An invalid hostname was used to access the server, please check your SLURL or Grid hostname.</string>
+ <string name="CertExpired">The certificate returned by the Grid appears to be expired. Please check your system clock, or contact your Grid administrator.</string>
+ <string name="CertKeyUsage">The certificate returned by the server could not be used for SSL. Please contact your Grid administrator.</string>
+ <string name="CertBasicConstraints">Too many certificates were in the servers Certificate chain. Please contact your Grid administrator.</string>
+ <string name="CertInvalidSignature">The certificate signature returned by the Grid server could not be verified. Please contact your Grid administrator.</string>
<string name="LoginFailedNoNetwork">Network error: Could not establish connection, please check your network connection.</string>
<string name="LoginFailed">Login failed.</string>
@@ -88,7 +88,7 @@ We are very sorry for the inconvenience.</string>
Logins are currently restricted to employees only.
Check www.secondlife.com/status for updates.</string>
<string name="LoginFailedPremiumOnly">Second Life logins are temporarily restricted in order to make sure that those in-world have the best possible experience.
-
+
People with free accounts will not be able to access Second Life during this time, to make room for those who have paid for Second Life.</string>
<string name="LoginFailedComputerProhibited">Second Life cannot be accessed from this computer.
If you feel this is an error, please contact
@@ -164,10 +164,18 @@ Please try logging in again in a minute.</string>
<string name="TooltipLand">Land:</string>
<string name="TooltipMustSingleDrop">Only a single item can be dragged here</string>
<string name="TooltipPrice" value="L$[AMOUNT]: "/>
- <string name="TooltipOutboxNoTransfer">One or more of these objects cannot be sold or transferred to another user.</string>
- <string name="TooltipOutboxWorn">You are wearing one or more of these objects. Remove them from your avatar and try moving them again.</string>
- <string name="TooltipOutboxFolderLevels">This folder has too many levels of subfolders. Rearrange the interior folders to a maximum of 4 levels deep (Root Folder contains A contains B contains C).</string>
- <string name="TooltipOutboxTooManyObjects">This folder contains more than 200 objects. Box some of the items to reduce the object count.</string>
+
+ <string name="TooltipOutboxDragToWorld">You can not rez items in your merchant outbox</string>
+ <string name="TooltipOutboxNoTransfer">One or more of these objects cannot be sold or transferred.</string>
+ <string name="TooltipOutboxNotInInventory">Your merchant outbox can only accept items directly from your inventory</string>
+ <string name="TooltipOutboxWorn">You can not put items you are wearing into your merchant outbox</string>
+ <string name="TooltipOutboxCallingCard">You can not put calling cards into your merchant outbox</string>
+ <string name="TooltipOutboxFolderLevels">Depth of nested folders exceeds 3</string>
+ <string name="TooltipOutboxTooManyFolders">Subfolder count in top-level folder exceeds 20</string>
+ <string name="TooltipOutboxTooManyObjects">Item count in top-level folder exceeds 200</string>
+
+ <string name="TooltipDragOntoOwnChild">You can't move a folder into its child</string>
+ <string name="TooltipDragOntoSelf">You can't move a folder into itself</string>
<!-- tooltips for Urls -->
<string name="TooltipHttpUrl">Click to view this web page</string>
@@ -188,7 +196,7 @@ Please try logging in again in a minute.</string>
<string name="TooltipObjectIMUrl">Click to view this object's description</string>
<string name="TooltipMapUrl">Click to view this location on a map</string>
<string name="TooltipSLAPP">Click to run the secondlife:// command</string>
- <string name="CurrentURL" value=" CurrentURL: [CurrentURL]" />
+ <string name="CurrentURL" value=" CurrentURL: [CurrentURL]" />
<!-- text for SLURL labels -->
<string name="SLurlLabelTeleport">Teleport to</string>
@@ -427,9 +435,10 @@ Please try logging in again in a minute.</string>
<string name="compressed_image_files">Compressed Images</string>
<string name="load_files">Load Files</string>
<string name="choose_the_directory">Choose Directory</string>
+ <string name="script_files">Scripts</string>
- <!-- LSL Usage Hover Tips -->
- <!-- NOTE: For now these are set as translate="false", until DEV-40761 is implemented (to internationalize the rest of tooltips in the same window).
+ <!-- LSL Usage Hover Tips -->
+ <!-- NOTE: For now these are set as translate="false", until DEV-40761 is implemented (to internationalize the rest of tooltips in the same window).
This has no effect on viewer code, but prevents Linden Lab internal localization tool from scraping these strings. -->
<string name="LSLTipSleepTime" translate="false">
Sleeps script for [SLEEP_TIME] seconds.
@@ -1950,7 +1959,7 @@ Returns a string with the requested data about the region
<string name="physics">Physics</string>
<string name="invalid">invalid</string>
<string name="none">none</string>
-
+
<!-- Not Worn Wearable Types -->
<string name="shirt_not_worn">Shirt not worn</string>
<string name="pants_not_worn">Pants not worn</string>
@@ -1987,7 +1996,7 @@ Returns a string with the requested data about the region
<!-- Wearable List-->
<string name="NewWearable">New [WEARABLE_ITEM]</string>
-
+
<!-- LLGroupNotify -->
<!-- used in the construction of a Group Notice blue dialog box, buttons, tooltip etc. Seems to be no longer utilized by code in Viewer 2.0 -->
<string name="next">Next</string>
@@ -2028,24 +2037,28 @@ Returns a string with the requested data about the region
<string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string>
<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>
<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
- <string name="InventoryInboxNoItems">When you purchase or otherwise receive an item, it will appear here so you can drag it to a folder in your inventory, or delete it if you do not wish to keep it.</string>
- <string name="MarketplaceURL">http://marketplace.[DOMAIN_NAME]</string>
- <string name="MarketplaceURL_CreateStore">http://marketplace.[DOMAIN_NAME]/create_store</string>
- <string name="MarketplaceURL_LearnMore">http://marketplace.[DOMAIN_NAME]/learn_more</string>
- <string name="InventoryOutboxCreationErrorTitle">Your Merchant Outbox is not properly configured</string>
- <string name="InventoryOutboxCreationErrorTooltip">Merchant Outbox configuration error</string>
- <string name="InventoryOutboxCreationError">Please contact Customer Service to correct the problem.</string>
- <string name="InventoryOutboxNotMerchantTitle">Anyone can sell items on the Marketplace</string>
- <string name="InventoryOutboxNotMerchantTooltip">Become a merchant!</string>
- <string name="InventoryOutboxNotMerchant">[[MARKETPLACE_URL] The Second Life Marketplace] offers more than one million virtual products for sale, all of them created by Residents. You, too, can sell items you create, as well as some of the items you have purchased. It’s easy and setup is free. [[LEARN_MORE_URL] Learn more] or [[CREATE_STORE_URL] create a store] on the Marketplace to get started.</string>
- <string name="InventoryOutboxNoItemsTitle">A new way to send items to the Marketplace</string>
- <string name="InventoryOutboxNoItemsTooltip">Drag and drop items here to prepare them for sale on the Marketplace</string>
- <string name="InventoryOutboxNoItems">Drag items or folders that you wish to sell into this area. A copy of the item will appear, leaving your inventory unchanged, unless you have dragged a no-copy item. When you are ready to send the items to the Marketplace, click the Upload button. Once your items have been moved to your Marketplace Inventory, they will disappear from this folder.</string>
+ <string name="InventoryInboxNoItems">Certain items you receive, such as premium gifts, will appear here. You may then drag them into your inventory.</string>
+ <string name="MarketplaceURL">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/</string>
+ <string name="MarketplaceURL_CreateStore">http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4</string>
+ <string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string>
+ <string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string>
+ <string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string>
+ <string name="InventoryOutboxNotMerchantTitle">Anyone can sell items on the Marketplace.</string>
+ <string name="InventoryOutboxNotMerchantTooltip"></string>
+ <string name="InventoryOutboxNotMerchant">
+If you'd like to become a merchant, you'll need to [[MARKETPLACE_CREATE_STORE_URL] create a Marketplace store].
+ </string>
+ <string name="InventoryOutboxNoItemsTitle">Your outbox is empty.</string>
+ <string name="InventoryOutboxNoItemsTooltip"></string>
+ <string name="InventoryOutboxNoItems">
+Drag folders to this area and click "Send to Marketplace" to list them for sale on the [[MARKETPLACE_DASHBOARD_URL] Marketplace].
+ </string>
<string name="Marketplace Error None">No errors</string>
<string name="Marketplace Error Not Merchant">Error: Before sending items to the Marketplace you will need to set yourself up as a merchant (free of charge).</string>
<string name="Marketplace Error Empty Folder">Error: This folder has no contents.</string>
- <string name="Marketplace Error Unassociated Products">Error: This item failed to upload because your merchant account has too many items unassociated with products. To fix this error, login to the marketplace website and reduce your unassociated item count.</string>
+ <string name="Marketplace Error Unassociated Products">Error: This item failed to upload because your merchant account has too many items unassociated with products. To fix this error, log in to the marketplace website and reduce your unassociated item count.</string>
+
<string name="Marketplace Error Object Limit">Error: This item contains too many objects. Fix this error by placing objects together in boxes to reduce the total count to less than 200.</string>
<string name="Marketplace Error Folder Depth">Error: This item contains too many levels of nested folders. Reorganize it to a maximum of 3 levels of nested folders.</string>
<string name="Marketplace Error Unsellable Item">Error: This item can not be sold on the marketplace.</string>
@@ -2314,7 +2327,7 @@ Returns a string with the requested data about the region
<string name="ScriptLimitsRequestWrongRegion">Error: script information is only available in your current region</string>
<string name="ScriptLimitsRequestWaiting">Retrieving information...</string>
<string name="ScriptLimitsRequestDontOwnParcel">You do not have permission to examine this parcel</string>
-
+
<string name="SITTING_ON">Sitting On</string>
<string name="ATTACH_CHEST">Chest</string>
<string name="ATTACH_HEAD">Head</string>
@@ -2354,7 +2367,7 @@ Returns a string with the requested data about the region
<string name="ATTACH_HUD_BOTTOM_LEFT">HUD Bottom Left</string>
<string name="ATTACH_HUD_BOTTOM">HUD Bottom</string>
<string name="ATTACH_HUD_BOTTOM_RIGHT">HUD Bottom Right</string>
-
+
<!-- script editor -->
<string name="CursorPos">Line [LINE], Column [COLUMN]</string>
@@ -2367,7 +2380,7 @@ Returns a string with the requested data about the region
<!-- panel contents -->
<string name="PanelContentsTooltip">Content of object</string>
- <string name="PanelContentsNewScript">New Script</string>
+ <string name="PanelContentsNewScript">New Script</string>
<!-- panel preferences general -->
<string name="BusyModeResponseDefault">The Resident you messaged is in &apos;busy mode&apos; which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.</string>
@@ -2397,7 +2410,7 @@ Returns a string with the requested data about the region
<!-- panel classified -->
<string name="ClassifiedClicksTxt">Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile</string>
<string name="ClassifiedUpdateAfterPublish">(will update after publish)</string>
-
+
<!-- panel picks -->
<string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string>
<string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string>
@@ -3274,7 +3287,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
You have blocked this Resident. Sending a message will automatically unblock them.
</string>
<!--Some times string name is getting from the body of server response.
- For ex.: from gIMMgr::showSessionStartError in the LLViewerChatterBoxSessionStartReply::post.
+ For ex.: from gIMMgr::showSessionStartError in the LLViewerChatterBoxSessionStartReply::post.
In case of the EXT-3115 issue 'generic' is passed into the gIMMgr::showSessionStartError as a string name.
Also there are some other places where "generic" is used.
So, let add string with name="generic" with the same value as "generic_request_error" -->
@@ -3300,7 +3313,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
You are not a session moderator.
</string>
<!--Some times string name is getting from the body of server response.
- For ex.: from gIMMgr::showSessionStartError in the LLViewerChatterBoxSessionStartReply::post.
+ For ex.: from gIMMgr::showSessionStartError in the LLViewerChatterBoxSessionStartReply::post.
In case of the EXT-3562 issue 'muted' is passed into the gIMMgr::showSessionStartError as a string name.
So, let add string with name="muted" with the same value as "muted_error" -->
<string name="muted">
@@ -3313,12 +3326,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Unable to add users to chat session with [RECIPIENT].
</string>
<!--Some times string name is getting from the body of server response.
- For ex.: from gIMMgr::showSessionStartError in the LLViewerChatterBoxSessionStartReply::post.
+ For ex.: from gIMMgr::showSessionStartError in the LLViewerChatterBoxSessionStartReply::post.
In case of the EXT-3562 issue 'message' is passed into the gIMMgr::showSessionStartError as a string name.
So, let add string with name="message" with the same value as "message_session_event" -->
<string name="message">
Unable to send your message to the chat session with [RECIPIENT].
- </string>
+ </string>
<string name="message_session_event">
Unable to send your message to the chat session with [RECIPIENT].
</string>
@@ -3326,7 +3339,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Error while moderating.
</string>
<!--Some times string name is getting from the body of server response.
- For ex.: from gIMMgr::showSessionStartError in the LLViewerChatterBoxSessionStartReply::post.
+ For ex.: from gIMMgr::showSessionStartError in the LLViewerChatterBoxSessionStartReply::post.
In case of the EXT-3459 issue 'removed' is passed into the gIMMgr::showSessionStartError as a string name.
So, let add string with name="removed" with the same value as "removed_from_group" -->
<string name="removed">
@@ -3347,9 +3360,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="session_initialization_timed_out_error">
The session initialization is timed out
</string>
-
+
<string name="Home position set.">Home position set.</string>
-
+
<string name="voice_morphing_url">http://secondlife.com/landing/voicemorphing</string>
<!-- Financial operations strings -->
@@ -3371,20 +3384,20 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="to join a group">to join a group</string>
<string name="to upload">to upload</string>
<string name="to publish a classified ad">to publish a classified ad</string>
-
+
<string name="giving">Giving L$ [AMOUNT]</string>
<string name="uploading_costs">Uploading costs L$ [AMOUNT]</string>
<string name="this_costs">This costs L$ [AMOUNT]</string>
<string name="buying_selected_land">Buying selected land for L$ [AMOUNT]</string>
<string name="this_object_costs">This object costs L$ [AMOUNT]</string>
-
+
<string name="group_role_everyone">Everyone</string>
<string name="group_role_officers">Officers</string>
<string name="group_role_owners">Owners</string>
<string name="group_member_status_online">Online</string>
<string name="uploading_abuse_report">Uploading...
-
+
Abuse Report</string>
<!-- names for new inventory items-->
@@ -3478,23 +3491,23 @@ Abuse Report</string>
<!-- birth date format shared by avatar inspector and profile panels -->
<string name="AvatarBirthDateFormat">[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]</string>
-
+
<string name="DefaultMimeType">none/none</string>
<string name="texture_load_dimensions_error">Can't load images larger than [WIDTH]*[HEIGHT]</string>
<!-- language specific white-space characters, delimiters, spacers, item separation symbols -->
<string name="sentences_separator" value=" "></string>
<string name="words_separator" value=", "/>
-
+
<string name="server_is_down">
Despite our best efforts, something unexpected has gone wrong.
- Please check status.secondlifegrid.net to see if there is a known problem with the service.
+ Please check status.secondlifegrid.net to see if there is a known problem with the service.
If you continue to experience problems, please check your network and firewall setup.
</string>
- <!-- overriding datetime formating.
- didn't translate if this is not needed for current localization
+ <!-- overriding datetime formating.
+ didn't translate if this is not needed for current localization
-->
<string name="dateTimeWeekdaysNames">Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday</string>
<string name="dateTimeWeekdaysShortNames">Sun:Mon:Tue:Wed:Thu:Fri:Sat</string>
@@ -3527,7 +3540,7 @@ Abuse Report</string>
<string name="DeleteItem">Delete selected item?</string>
<string name="EmptyOutfitText">There are no items in this outfit</string>
-
+
<!-- External editor status codes -->
<string name="ExternalEditorNotSet">Select an editor using the ExternalEditor setting.</string>
<string name="ExternalEditorNotFound">Cannot find the external editor you specified.
@@ -3680,6 +3693,7 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Marketplace_Label">Marketplace</string>
<string name="Command_MiniMap_Label">Mini-map</string>
<string name="Command_Move_Label">Walk / run / fly</string>
+ <string name="Command_Outbox_Label">Merchant outbox</string>
<string name="Command_People_Label">People</string>
<string name="Command_Picks_Label">Picks</string>
<string name="Command_Places_Label">Places</string>
@@ -3705,6 +3719,7 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Marketplace_Tooltip">Go shopping</string>
<string name="Command_MiniMap_Tooltip">Show nearby people</string>
<string name="Command_Move_Tooltip">Moving your avatar</string>
+ <string name="Command_Outbox_Tooltip">Transfer items to your marketplace for sale</string>
<string name="Command_People_Tooltip">Friends, groups, and nearby people</string>
<string name="Command_Picks_Tooltip">Places to show as favorites in your profile</string>
<string name="Command_Places_Tooltip">Places you've saved</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
index 0792996107..d19c47f54f 100644
--- a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
+++ b/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
@@ -6,14 +6,4 @@
item_top_pad="4"
selection_image="Rounded_Square"
>
- <error_badge
- label=" "
- label_offset_horiz="-1"
- location="right"
- padding_horiz="12.5"
- padding_vert="2"
- location_offset_hcenter="-23"
- image="Error_Tag_Background"
- image_color="Black"
- />
</outbox_folder_view_folder>
diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
index e3f2072819..3964569da2 100644
--- a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<outbox_inventory_panel show_load_status="false" />
+<outbox_inventory_panel show_empty_message="false" show_load_status="false" />
diff --git a/indra/newview/skins/default/xui/en/widgets/window_shade.xml b/indra/newview/skins/default/xui/en/widgets/window_shade.xml
new file mode 100644
index 0000000000..23eb2f13fb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/window_shade.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<window_shade shade_color="0 0 0 0.5"/>
diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml
index b7c9cc27ac..307b61133f 100644
--- a/indra/newview/skins/default/xui/es/floater_about.xml
+++ b/indra/newview/skins/default/xui/es/floater_about.xml
@@ -67,32 +67,34 @@ Versión del servidor de voz: [VOICE_VERSION]
<panel label="Licencias" name="licenses_panel">
<text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
-APR Copyright (C) 2000-2004 The Apache Software Foundation
-Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
-cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
-DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
-expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
-FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
-GL Copyright (C) 1999-2004 Brian Paul.
-GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University y David Luebke, Brenden Schubert, University of Virginia.
-google-perftools Copyright (c) 2005, Google Inc.
-Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
-jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
-jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
-ogg/vorbis Copyright (C) 2001, Xiphophorus
-OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
-PCRE Copyright (c) 1997-2008 University of Cambridge
-SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
-SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
-zlib Copyright (C) 1995-2002 Jean-loup Gailly y Mark Adler.
-google-perftools Copyright (c) 2005, Google Inc.
+ APR Copyright (C) 2000-2004 The Apache Software Foundation
+ Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
+ expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+ FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ GL Copyright (C) 1999-2004 Brian Paul.
+ GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
+ google-perftools Copyright (c) 2005, Google Inc.
+ Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
+ jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
+ jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
+ ogg/vorbis Copyright (C) 2001, Xiphophorus
+ OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2008 University of Cambridge
+ SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+ SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
+ zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
+ google-perftools Copyright (c) 2005, Google Inc.
-El visor de Second Life utiliza Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (y los propietarios de las licencias). Reservados todos los derechos. Consulta www.havok.com si deseas obtener más información.
+ El visor de Second Life usa Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (y sus licenciadores). Reservados todos los derechos. Vea los detalles en www.havok.com.
-Reservados todos los derechos. Consulta las licencias en .txt si deseas obtener más información.
+ Este software contiene código fuente suministrado por NVIDIA Corporation.
-Codificación de sonido del chat de voz: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
+ Reservados todos los derechos. Consulte los detalles en licenses.txt.
+
+ Codificación del audio del chat de voz: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
</text_editor>
</panel>
</tab_container>
diff --git a/indra/newview/skins/default/xui/es/floater_about_land.xml b/indra/newview/skins/default/xui/es/floater_about_land.xml
index b6391e28a0..6b8a1ff906 100644
--- a/indra/newview/skins/default/xui/es/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/es/floater_about_land.xml
@@ -130,7 +130,7 @@ Vaya al menú Mundo &gt; Acerca del terreno o seleccione otra parcela para ver s
Tráfico:
</text>
<text name="DwellText">
- 0
+ Cargando...
</text>
<button label="Comprar terreno" left="130" name="Buy Land..." width="125"/>
<button label="Venta Linden" name="Linden Sale..." tool_tip="El terreno debe estar en propiedad, con contenido, y no estar en subasta."/>
@@ -309,13 +309,15 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda.
Sin &apos;empujones&apos; (prevalece lo marcado en la región)
</panel.string>
<panel.string name="see_avs_text">
- Ver a los residentes de esta parcela y chatear con ellos
+ Los avatares de otras parcelas pueden ver
</panel.string>
<text name="allow_label">
Permitir a otros Residentes:
</text>
- <check_box label="Editar el terreno" name="edit land check" tool_tip="Si se marca, cualquiera podrá modificar su terreno. Mejor dejarlo desmarcado, pues usted siempre puede modificar su terreno."/>
- <check_box label="Volar" name="check fly" tool_tip="Si se marca, los residentes podrán volar en su terreno. Si no, sólo podrán volar al cruzarlo o hasta que aterricen en él."/>
+ <text name="allow_label0">
+ Volar:
+ </text>
+ <check_box label="Todos" name="check fly" tool_tip="Si se marca, los residentes podrán volar en su terreno. Si no, sólo podrán volar al cruzarlo o hasta que aterricen en él."/>
<text name="allow_label2">
Crear objetos:
</text>
@@ -331,9 +333,6 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda.
</text>
<check_box label="Todos los residentes" name="check other scripts"/>
<check_box label="El grupo" name="check group scripts"/>
- <text name="land_options_label">
- Opciones del terreno:
- </text>
<check_box label="Seguro (sin daño)" name="check safe" tool_tip="Si se marca, convierte el terreno en &apos;seguro&apos;, desactivando el daño en combate. Si no, se activa el daño en combate."/>
<check_box label="Sin &apos;empujones&apos;" name="PushRestrictCheck" tool_tip="Previene scripts que empujen. Marcando esta opción prevendrá que en su terreno haya comportamientos destructivos."/>
<check_box label="Mostrar el sitio en la búsqueda (30 L$/semana)" name="ShowDirectoryCheck" tool_tip="Let people see this parcel in search results"/>
@@ -374,9 +373,9 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda.
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Pulse para elegir una imagen"/>
<text name="allow_label5">
- Permitir a los residentes de otras parcelas:
+ a los avatares de esta parcela y chatear con ellos
</text>
- <check_box label="Ver los avatares" name="SeeAvatarsCheck" tool_tip="Permite que los residentes de otras parcelas vean a los residentes de ésta y chateen con ellos, y también que tú puedas verles y chatear con ellos."/>
+ <check_box label="Ver los avatares" name="SeeAvatarsCheck" tool_tip="Permite que los avatares de otras parcelas vean a los avatares de ésta y chateen con ellos, y también que tú puedas verles y chatear con ellos."/>
<text name="landing_point">
Punto de llegada: [LANDING]
</text>
diff --git a/indra/newview/skins/default/xui/es/floater_avatar.xml b/indra/newview/skins/default/xui/es/floater_avatar.xml
index 7c87fbe01c..21d202309f 100644
--- a/indra/newview/skins/default/xui/es/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/es/floater_avatar.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Avatar" title="SELECTOR DE AVATAR"/>
+<floater name="Avatar" title="ELIGE UN AVATAR"/>
diff --git a/indra/newview/skins/default/xui/es/floater_camera.xml b/indra/newview/skins/default/xui/es/floater_camera.xml
index f8911f3a4a..b0704ab788 100644
--- a/indra/newview/skins/default/xui/es/floater_camera.xml
+++ b/indra/newview/skins/default/xui/es/floater_camera.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="camera_floater" title="VER">
+<floater name="camera_floater" title="CONTROLES DE LA CÁMARA">
<floater.string name="rotate_tooltip">
Girar la cámara alrededor de lo enfocado
</floater.string>
diff --git a/indra/newview/skins/default/xui/es/floater_chat_bar.xml b/indra/newview/skins/default/xui/es/floater_chat_bar.xml
index 5e5ef616b8..2e94805057 100644
--- a/indra/newview/skins/default/xui/es/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/es/floater_chat_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="chat_bar" title="CHAT">
- <panel>
+ <panel name="bottom_panel">
<line_editor label="Pulsa aquí para chatear." name="chat_box" tool_tip="Pulsa Enter para decirlo o Ctrl+Enter para gritarlo"/>
<button name="show_nearby_chat" tool_tip="Muestra o esconde el registro del chat"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/floater_hardware_settings.xml b/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
index 0150241d9a..b96076836b 100644
--- a/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
@@ -4,7 +4,7 @@
Filtrado:
</text>
<check_box label="Filtrado anisotrópico (más lento si se activa)" name="ani"/>
- <text name="Antialiasing:">
+ <text name="antialiasing label">
Antialiasing:
</text>
<combo_box label="Antialiasing" name="fsaa" width="94">
diff --git a/indra/newview/skins/default/xui/es/floater_model_preview.xml b/indra/newview/skins/default/xui/es/floater_model_preview.xml
index 3e77453612..ab3ba5aed7 100644
--- a/indra/newview/skins/default/xui/es/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/es/floater_model_preview.xml
@@ -4,6 +4,9 @@
<string name="status_parse_error">
Error: Problema de análisis de DAE - consulta los datos en el registro.
</string>
+ <string name="status_material_mismatch">
+ Error: el material del modelo no es un subconjunto del modelo de referencia.
+ </string>
<string name="status_reading_file">
Cargando...
</string>
diff --git a/indra/newview/skins/default/xui/es/floater_model_wizard.xml b/indra/newview/skins/default/xui/es/floater_model_wizard.xml
index c4eb5e955a..e27db5a1c4 100644
--- a/indra/newview/skins/default/xui/es/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/es/floater_model_wizard.xml
@@ -20,6 +20,9 @@
Elige el archivo de modelo que deseas subir
</text>
<button label="Buscar..." label_selected="Buscar..." name="browse"/>
+ <text name="Model types">
+ ‎Second Life admite los archivos COLLADA (.dae)
+ </text>
<text name="dimensions">
X Y Z
</text>
diff --git a/indra/newview/skins/default/xui/es/floater_moveview.xml b/indra/newview/skins/default/xui/es/floater_moveview.xml
index b29fe04848..0e7b950bd3 100644
--- a/indra/newview/skins/default/xui/es/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/es/floater_moveview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="move_floater" title="MOVERME">
+<floater name="move_floater" title="CAMINAR / CORRER / VOLAR">
<string name="walk_forward_tooltip">
Caminar hacia adelante (cursor arriba o W)
</string>
diff --git a/indra/newview/skins/default/xui/es/floater_snapshot.xml b/indra/newview/skins/default/xui/es/floater_snapshot.xml
index eafc623ea9..23078b3a55 100644
--- a/indra/newview/skins/default/xui/es/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/es/floater_snapshot.xml
@@ -3,73 +3,63 @@
<floater.string name="unknown">
desconocido
</floater.string>
- <radio_group label="Tipo de foto" name="snapshot_type_radio">
- <radio_item label="Correo-e" name="postcard"/>
- <radio_item label="Mi inventario ([AMOUNT] L$)" name="texture"/>
- <radio_item label="Guardar en mi ordenador" name="local"/>
- </radio_group>
+ <string name="postcard_progress_str">
+ Enviando el correo electrónico
+ </string>
+ <string name="profile_progress_str">
+ Publicando
+ </string>
+ <string name="inventory_progress_str">
+ Guardando en el inventario
+ </string>
+ <string name="local_progress_str">
+ Guardando en el equipo
+ </string>
+ <string name="profile_succeeded_str">
+ Imagen subida
+ </string>
+ <string name="postcard_succeeded_str">
+ Correo electrónico enviado
+ </string>
+ <string name="inventory_succeeded_str">
+ ¡Guardado en el inventario!
+ </string>
+ <string name="local_succeeded_str">
+ ¡Guardado en el equipo!
+ </string>
+ <string name="profile_failed_str">
+ Error al subir la imagen a los comentarios de tu perfil.
+ </string>
+ <string name="postcard_failed_str">
+ Error al enviar el correo electrónico.
+ </string>
+ <string name="inventory_failed_str">
+ Error al guardar en el inventario.
+ </string>
+ <string name="local_failed_str">
+ Error al guardar en el equipo.
+ </string>
+ <button name="advanced_options_btn" tool_tip="Opciones avanzadas"/>
+ <text name="image_res_text">
+ [WIDTH] x [HEIGHT] px
+ </text>
<text name="file_size_label">
[SIZE] kB
</text>
- <button label="Actualizar la foto" name="new_snapshot_btn"/>
- <button label="Enviar" name="send_btn"/>
- <button label="Ahorro ([AMOUNT] L$)" name="upload_btn"/>
- <flyout_button label="Guardar" name="save_btn" tool_tip="Guardar la imagen en un archivo">
- <flyout_button.item label="Guardar" name="save_item"/>
- <flyout_button.item label="Guardar como..." name="saveas_item"/>
- </flyout_button>
- <button label="Más" name="more_btn" tool_tip="Opciones avanzadas"/>
- <button label="Menos" name="less_btn" tool_tip="Opciones avanzadas"/>
- <button label="Cancelar" name="discard_btn"/>
- <text name="type_label2">
- Tamaño
- </text>
- <text name="format_label">
- Formato
- </text>
- <combo_box label="Resolución" name="postcard_size_combo">
- <combo_box.item label="Ventana actual" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="Personalizado" name="Custom"/>
- </combo_box>
- <combo_box label="Resolución" name="texture_size_combo">
- <combo_box.item label="Ventana actual" name="CurrentWindow"/>
- <combo_box.item label="Pequeña (128x128)" name="Small(128x128)"/>
- <combo_box.item label="Mediana (256x256)" name="Medium(256x256)"/>
- <combo_box.item label="Grande (512x512)" name="Large(512x512)"/>
- <combo_box.item label="Personalizado" name="Custom"/>
- </combo_box>
- <combo_box label="Resolución" name="local_size_combo">
- <combo_box.item label="Ventana actual" name="CurrentWindow"/>
- <combo_box.item label="320x240" name="320x240"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1280x1024" name="1280x1024"/>
- <combo_box.item label="1600x1200" name="1600x1200"/>
- <combo_box.item label="Personalizado" name="Custom"/>
- </combo_box>
- <combo_box label="Formato" name="local_format_combo">
- <combo_box.item label="PNG" name="PNG"/>
- <combo_box.item label="JPEG" name="JPEG"/>
- <combo_box.item label="BMP" name="BMP"/>
- </combo_box>
- <spinner label="Ancho" name="snapshot_width"/>
- <spinner label="Altura" name="snapshot_height"/>
- <check_box label="Mantener las proporciones" name="keep_aspect_check"/>
- <slider label="Calidad de la imagen" name="image_quality_slider"/>
- <text name="layer_type_label">
- Captura:
- </text>
- <combo_box label="Capas de imagen" name="layer_types">
- <combo_box.item label="Colores" name="Colors"/>
- <combo_box.item label="Profundidad" name="Depth"/>
- </combo_box>
- <check_box label="Interfaz" name="ui_check"/>
- <check_box label="HUDs" name="hud_check"/>
- <check_box label="Mantener abierto después de guardar" name="keep_open_check"/>
- <check_box label="Congelar la toma (pantalla completa)" name="freeze_frame_check"/>
- <check_box label="Actualizar automáticamente" name="auto_snapshot_check"/>
+ <panel name="advanced_options_panel">
+ <text name="advanced_options_label">
+ OPCIONES AVANZADAS
+ </text>
+ <text name="layer_type_label">
+ Captura:
+ </text>
+ <combo_box label="Capas de imagen" name="layer_types">
+ <combo_box.item label="Colores" name="Colors"/>
+ <combo_box.item label="Profundidad" name="Depth"/>
+ </combo_box>
+ <check_box label="Interfaz" name="ui_check"/>
+ <check_box label="HUDs" name="hud_check"/>
+ <check_box label="Congelar la toma (pantalla completa)" name="freeze_frame_check"/>
+ <check_box label="Actualizar automáticamente" name="auto_snapshot_check"/>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_toybox.xml b/indra/newview/skins/default/xui/es/floater_toybox.xml
index b36a05a6e4..7275b0546b 100644
--- a/indra/newview/skins/default/xui/es/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/es/floater_toybox.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Toybox" title="PERSONALIZAR BARRAS DE HERRAMIENTAS">
+<floater name="Toybox" title="BOTONES DE LA BARRA DE HERRAMIENTAS">
<text name="toybox label 1">
Puedes agregar o quitar botones arrastrándolos a las barras de herramientas o desde ellas.
</text>
<text name="toybox label 2">
Los botones aparecerán como se muestra o solo como iconos, según la configuración de cada barra de herramientas.
</text>
+ <button label="Quitar todas las barras de herramientas" label_selected="Quitar todas las barras de herramientas" name="btn_clear_all"/>
<button label="Restaurar valores predeterminados" label_selected="Restaurar valores predeterminados" name="btn_restore_defaults"/>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_translation_settings.xml b/indra/newview/skins/default/xui/es/floater_translation_settings.xml
new file mode 100644
index 0000000000..765c9a05a2
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_translation_settings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_translation_settings" title="CONFIGURACIÓN DE LA TRADUCCIÓN DEL CHAT">
+ <string name="bing_api_key_not_verified">
+ appID de Bing no se ha confirmado. Vuelve a intentarlo.
+ </string>
+ <string name="google_api_key_not_verified">
+ La clave de API de Google no se ha confirmado. Vuelve a intentarlo.
+ </string>
+ <string name="bing_api_key_verified">
+ appID de Bing se ha confirmado.
+ </string>
+ <string name="google_api_key_verified">
+ La clave de API de Google se ha confirmado.
+ </string>
+ <check_box label="Activar la traducción automática durante el chat" name="translate_chat_checkbox"/>
+ <text name="translate_language_label">
+ Traducir el chat al:
+ </text>
+ <combo_box name="translate_language_combo">
+ <combo_box.item label="Predeterminado del sistema" name="System Default Language"/>
+ <combo_box.item label="Inglés" name="English"/>
+ <combo_box.item label="Dansk (danés)" name="Danish"/>
+ <combo_box.item label="Deutsch (alemán)" name="German"/>
+ <combo_box.item label="Español (español)" name="Spanish"/>
+ <combo_box.item label="Français (francés)" name="French"/>
+ <combo_box.item label="Italiano (italiano)" name="Italian"/>
+ <combo_box.item label="Magyar (húngaro)" name="Hungarian"/>
+ <combo_box.item label="Nederlands (neerlandés)" name="Dutch"/>
+ <combo_box.item label="Polski (polaco)" name="Polish"/>
+ <combo_box.item label="Português (portugués)" name="Portugese"/>
+ <combo_box.item label="Русский (ruso)" name="Russian"/>
+ <combo_box.item label="Türkçe (turco)" name="Turkish"/>
+ <combo_box.item label="Українська (ucraniano)" name="Ukrainian"/>
+ <combo_box.item label="中文 (正體) (Chino)" name="Chinese"/>
+ <combo_box.item label="日本語 (japonés)" name="Japanese"/>
+ <combo_box.item label="한국어 (coreano)" name="Korean"/>
+ </combo_box>
+ <text name="tip">
+ Elige el servicio de traducción:
+ </text>
+ <radio_group name="translation_service_rg">
+ <radio_item initial_value="bing" label="Bing Translator" name="bing"/>
+ <radio_item initial_value="google" label="Traductor de Google" name="google"/>
+ </radio_group>
+ <text name="bing_api_key_label">
+ [http://www.bing.com/developers/createapp.aspx AppID] de Bing:
+ </text>
+ <button label="Verificar" name="verify_bing_api_key_btn"/>
+ <text name="google_api_key_label">
+ [http://code.google.com/apis/language/translate/v2/getting_started.html#auth Clave de API] de Google:
+ </text>
+ <button label="Verificar" name="verify_google_api_key_btn"/>
+ <text name="google_links_text">
+ [http://code.google.com/apis/language/translate/v2/pricing.html Precios] | [https://code.google.com/apis/console Estadísticas]
+ </text>
+ <button label="OK" name="ok_btn"/>
+ <button label="Cancelar" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_voice_controls.xml b/indra/newview/skins/default/xui/es/floater_voice_controls.xml
index cefec2a7a1..eff21239be 100644
--- a/indra/newview/skins/default/xui/es/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/es/floater_voice_controls.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_voice_controls" title="CONTROLES DE LA VOZ">
<string name="title_nearby">
- Chat de voz
+ CONFIGURACIÓN DE VOZ
</string>
<string name="title_group">
- Multiconferencia de voz con [GROUP]
+ MULTICONFERENCIA DE VOZ CON [GROUP]
</string>
<string name="title_adhoc">
- Multiconferencia de voz
+ MULTICONFERENCIA DE VOZ
</string>
<string name="title_peer_2_peer">
- Llamada: [NAME]
+ LLAMADA A [NAME]
</string>
<string name="no_one_near">
Nadie cercano tiene activada la voz
diff --git a/indra/newview/skins/default/xui/es/menu_toolbars.xml b/indra/newview/skins/default/xui/es/menu_toolbars.xml
index f8ed1c54ca..63f3dc43bd 100644
--- a/indra/newview/skins/default/xui/es/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/es/menu_toolbars.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Toolbars Popup">
- <menu_item_call label="Elegir botones..." name="Chose Buttons"/>
+ <menu_item_call label="Quitar este botón" name="Remove button"/>
+ <menu_item_call label="Botones de la barra de herramientas..." name="Choose Buttons"/>
<menu_item_check label="Iconos y etiquetas" name="icons_with_text"/>
<menu_item_check label="Solo iconos" name="icons_only"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml
index f5cc2b9389..4762e3f4a4 100644
--- a/indra/newview/skins/default/xui/es/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/es/menu_viewer.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu_bar name="Main Menu">
<menu label="Yo" name="Me">
- <menu_item_call label="Panel de control..." name="Manage My Account">
- <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=es"/>
- </menu_item_call>
<menu_item_call label="Perfil..." name="Profile"/>
<menu_item_call label="Apariencia" name="ChangeOutfit"/>
+ <menu_item_call label="Elige un avatar..." name="Avatar Picker"/>
<menu_item_check label="Inventario..." name="Inventory"/>
- <menu_item_check label="Gestos..." name="Gestures"/>
- <menu_item_check label="Voz..." name="ShowVoice"/>
+ <menu_item_call label="Nueva ventana del inventario" name="NewInventoryWindow"/>
+ <menu_item_call label="Lugares..." name="Places"/>
+ <menu_item_call label="Destacados..." name="Picks"/>
+ <menu_item_call label="Controles de la cámara..." name="Camera Controls"/>
<menu label="Movimiento" name="Movement">
<menu_item_call label="Sentarte" name="Sit Down Here"/>
<menu_item_check label="Volar" name="Fly"/>
@@ -22,34 +22,39 @@
<menu_item_call label="Solicitar estatus de Administrador" name="Request Admin Options"/>
<menu_item_call label="Dejar el estatus de Administrador" name="Leave Admin Options"/>
<menu_item_call label="Comprar L$" name="Buy and Sell L$"/>
+ <menu_item_call label="Panel de control de la cuenta..." name="Manage My Account">
+ <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=es"/>
+ </menu_item_call>
<menu_item_call label="Preferencias..." name="Preferences"/>
- <menu_item_call label="Barras de herramientas..." name="Toolbars"/>
+ <menu_item_call label="Botones de la barra de herramientas..." name="Toolbars"/>
<menu_item_call label="Ocultar todos los controles" name="Hide UI"/>
<menu_item_call label="Salir de [APP_NAME]" name="Quit"/>
</menu>
<menu label="Comunicarme" name="Communicate">
- <menu_item_call label="Mis amigos" name="My Friends"/>
- <menu_item_call label="Mis grupos" name="My Groups"/>
- <menu_item_check label="Chat" name="Nearby Chat"/>
+ <menu_item_check label="Chat..." name="Nearby Chat"/>
+ <menu_item_check label="Hablar" name="Speak"/>
+ <menu_item_check label="Configuración de voz..." name="Nearby Voice"/>
+ <menu_item_check label="Transformación de voz..." name="ShowVoice"/>
+ <menu_item_check label="Gestos..." name="Gestures"/>
+ <menu_item_call label="Amigos" name="My Friends"/>
+ <menu_item_call label="Grupos" name="My Groups"/>
<menu_item_call label="Gente cerca" name="Active Speakers"/>
- <menu_item_check label="Chat de voz" name="Nearby Voice"/>
</menu>
<menu label="Mundo" name="World">
- <menu_item_check label="Minimapa" name="Mini-Map"/>
+ <menu_item_call label="Crear un hito de este sitio" name="Create Landmark Here"/>
+ <menu_item_call label="Destinos..." name="Destinations"/>
<menu_item_check label="Mapa del mundo" name="World Map"/>
+ <menu_item_check label="Minimapa" name="Mini-Map"/>
<menu_item_check label="Buscar" name="Search"/>
+ <menu_item_call label="Teleportar a la Base" name="Teleport Home"/>
+ <menu_item_call label="Fijar mi Base aquí" name="Set Home to Here"/>
<menu_item_call label="Foto" name="Take Snapshot"/>
- <menu_item_call label="Crear un hito de este sitio" name="Create Landmark Here"/>
- <menu label="Perfil del lugar" name="Land">
- <menu_item_call label="Perfil del lugar" name="Place Profile"/>
- <menu_item_call label="Acerca del terreno" name="About Land"/>
- <menu_item_call label="Región/Estado" name="Region/Estate"/>
- </menu>
+ <menu_item_call label="Perfil del lugar" name="Place Profile"/>
+ <menu_item_call label="Acerca del terreno" name="About Land"/>
+ <menu_item_call label="Región/Estado" name="Region/Estate"/>
+ <menu_item_call label="Mis terrenos..." name="My Land"/>
<menu_item_call label="Comprar este terreno" name="Buy Land"/>
- <menu_item_call label="Mi terreno" name="My Land"/>
<menu label="Mostrar" name="LandShow">
- <menu_item_check label="Controles del movimiento" name="Movement Controls"/>
- <menu_item_check label="Controles de la cámara" name="Camera Controls"/>
<menu_item_check label="Líneas de prohibición" name="Ban Lines"/>
<menu_item_check label="Balizas" name="beacons"/>
<menu_item_check label="Límites de las parcelas" name="Property Lines"/>
@@ -58,16 +63,15 @@
<menu_item_check label="Propiedades de la parcela" name="Parcel Properties"/>
<menu_item_check label="Menú Avanzado" name="Show Advanced Menu"/>
</menu>
- <menu_item_call label="Teleportar a la Base" name="Teleport Home"/>
- <menu_item_call label="Fijar mi Base aquí" name="Set Home to Here"/>
<menu label="Sol" name="Environment Settings">
<menu_item_call label="Amanecer" name="Sunrise"/>
<menu_item_call label="Mediodía" name="Noon"/>
<menu_item_call label="Atardecer" name="Sunset"/>
<menu_item_call label="Medianoche" name="Midnight"/>
+ <menu_item_call label="Usar configuración de región" name="Use Region Settings"/>
</menu>
- <menu label="Editor de entorno" name="Enviroment Editor">
- <menu_item_call label="Configuración de entorno..." name="Enviroment Settings"/>
+ <menu label="Editor de entorno" name="Environment Editor">
+ <menu_item_call label="Configuración del entorno..." name="Environment Settings"/>
<menu label="Agua predefinida" name="Water Presets">
<menu_item_call label="Nuevo predefinido..." name="new_water_preset"/>
<menu_item_call label="Editar predefinido..." name="edit_water_preset"/>
@@ -146,6 +150,7 @@
<menu_item_call label="Rehacer" name="Redo"/>
</menu>
<menu label="Ayuda" name="Help">
+ <menu_item_call label="Cómo..." name="How To"/>
<menu_item_call label="Ayuda de [SECOND_LIFE]" name="Second Life Help"/>
<menu_item_call label="Denunciar una infracción" name="Report Abuse"/>
<menu_item_call label="Informar de un fallo" name="Report Bug"/>
@@ -199,11 +204,10 @@
<menu_item_check label="Usar Plugin Read Thread" name="Use Plugin Read Thread"/>
<menu_item_call label="Vaciar la caché de grupo" name="ClearGroupCache"/>
<menu_item_check label="Vista subjetiva suavizada" name="Mouse Smoothing"/>
+ <menu_item_call label="Recuperar las teclas" name="Release Keys"/>
<menu label="Atajos de teclado" name="Shortcuts">
<menu_item_call label="Imagen ([COST] L$)..." name="Upload Image"/>
<menu_item_check label="Buscar" name="Search"/>
- <menu_item_call label="Recuperar las teclas" name="Release Keys"/>
- <menu_item_call label="Interfaz en el tamaño predeterminado" name="Set UI Size to Default"/>
<menu_item_check label="Mostrar el menú Avanzado - acceso directo antiguo" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="Cerrar la ventana" name="Close Window"/>
<menu_item_call label="Cerrar todas las ventanas" name="Close All Windows"/>
@@ -272,6 +276,7 @@
<menu_item_check label="Actualizar el tipo" name="Update Type"/>
<menu_item_check label="Información sobre el nivel de detalle" name="LOD Info"/>
<menu_item_check label="Crear cola" name="Build Queue"/>
+ <menu_item_check label="Vectores de viento" name="Wind Vectors"/>
<menu_item_check label="Complejidad del renderizado" name="rendercomplexity"/>
<menu_item_check label="Esculpir" name="Sculpt"/>
</menu>
@@ -281,7 +286,6 @@
<menu_item_check label="Luces y sombras" name="Lighting and Shadows"/>
<menu_item_check label="Sombras del sol/la luna/proyectores" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO y sombras suavizadas" name="SSAO and Shadow Smoothing"/>
- <menu_item_check label="Iluminación global (experimental)" name="Global Illumination"/>
<menu_item_check label="Capas alfa automáticas (deferidas)" name="Automatic Alpha Masks (deferred)"/>
<menu_item_check label="Capas alfa automáticas (no deferidas)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Animation Textures" name="Animation Textures"/>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 9591b424fc..e0a20683c5 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -1114,8 +1114,13 @@ El precio de compra del terreno no se le devolverá al propietario. Si se vende
<notification name="DisplaySetToSafe">
Las configuraciones que se muestran se han fijado en los niveles guardados, pues especificaste la opción de guardarlos.
</notification>
- <notification name="DisplaySetToRecommended">
- Las configuraciones que se muestran se han fijado en los niveles recomendados para la configuración de tu sistema.
+ <notification name="DisplaySetToRecommendedGPUChange">
+ La configuración de pantalla se ha establecido en los niveles recomendados porque tu tarjeta de gráficos ha cambiado
+de &apos;[LAST_GPU]&apos;
+a &apos;[THIS_GPU]&apos;
+ </notification>
+ <notification name="DisplaySetToRecommendedFeatureChange">
+ La configuración de pantalla se ha establecido en los niveles recomendados a causa de un cambio en el subsistema de renderizado.
</notification>
<notification name="ErrorMessage">
[ERROR_MESSAGE]
@@ -1437,7 +1442,7 @@ Debemos reiniciar [APP_NAME] para instalar la actualización.
<usetemplate ignoretext="Confirmar antes de devolver objetos a sus propietarios." name="okcancelignore" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="GroupLeaveConfirmMember">
- Actualmente, eres miembro del grupo [GROUP].
+ Actualmente, eres miembro del grupo &lt;nolink&gt;[GROUP]&lt;/nolink&gt;.
¿Dejar el grupo?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
@@ -1920,7 +1925,13 @@ Dado que estos objetos tienen scripts, moverlos a tu inventario puede provocar u
<usetemplate ignoretext="Confirmar antes de salir" name="okcancelignore" notext="No salir" yestext="Salir"/>
</notification>
<notification name="ConfirmRestoreToybox">
- ¿Estás seguro de que quieres restaurar los botones y barras de herramientas predeterminados?
+ Esta acción restaurará los botones y barras de herramientas predeterminados.
+
+Esta acción no se puede deshacer.
+ <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="ConfirmClearAllToybox">
+ Esta acción volverá a colocar todos los botones a la caja de herramientas y las barras de herramientas aparecerán vacías.
Esta acción no se puede deshacer.
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
@@ -2244,14 +2255,16 @@ Por favor, selecciona un sólo objeto.
Se ha rehusado tu tarjeta de visita.
</notification>
<notification name="TeleportToLandmark">
- Puedes teleportarte a lugares como &apos;[NAME]&apos; abriendo el panel Lugares -a la derecha de tu pantalla- y seleccionando la sección Hitos.
-Pulsa en un hito para seleccionarlo, y, luego, pulsa &apos;Teleportar&apos; en la parte inferior del panel.
-(También puedes pulsar dos veces en el hito o pulsarlo con el botón derecho del ratón y elegir &apos;Teleportar&apos;.)
+ Para teleportarte a lugares como &apos;[NAME]&apos;, pulsa el botón &quot;Lugares&quot;,
+ y selecciona la pestaña Hitos en la ventana que se abre. Pulsa en un
+ hito para seleccionarlo y luego pulsa &apos;Teleportar&apos; en la parte inferior de la ventana.
+ (También puedes pulsar dos veces en el hito o pulsarlo con el botón derecho del ratón y
+ elegir &apos;Teleportar&apos;.)
</notification>
<notification name="TeleportToPerson">
- Puedes contactar con un Residente como &apos;[NAME]&apos; abriendo el panel Gente en el lado derecho de tu pantalla.
-Elige al Residente de la lista y pulsa &apos;MI&apos; en la parte inferior del panel.
-(También puedes pulsar dos veces en su nombre o pulsarlo con el botón derecho y elegir &apos;MI&apos;).
+ Para ponerte en contacto con Residentes como &apos;[NAME]&apos;, pulsa el botón &quot;Gente&quot;, selecciona un Residente en la ventana que se abre y después pulsa en &apos;MI&apos; en
+ la parte inferior de la ventana.
+ (También puedes pulsar dos veces en su nombre o pulsarlo con el botón derecho y elegir &apos;MI&apos;).
</notification>
<notification name="CantSelectLandFromMultipleRegions">
No puedes seleccionar un terreno que cruce las fronteras entre servidores.
@@ -2272,6 +2285,9 @@ Inténtalo seleccionando un trozo más pequeño de terreno.
<notification name="PaymentSent">
[MESSAGE]
</notification>
+ <notification name="PaymentFailure">
+ [MESSAGE]
+ </notification>
<notification name="EventNotification">
Notificación de un evento:
@@ -2526,10 +2542,10 @@ Por favor, vuelve a intentarlo en unos momentos.
</form>
</notification>
<notification name="FriendshipAccepted">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; ha aceptado tu oferta de amistad.
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; ha aceptado tu ofrecimiento de amistad.
</notification>
<notification name="FriendshipDeclined">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; ha rehusado tu oferta de amistad.
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; ha rechazado tu ofrecimiento de amistad.
</notification>
<notification name="FriendshipAcceptedByMe">
Aceptado el ofrecimiento de amistad.
diff --git a/indra/newview/skins/default/xui/es/panel_edit_skin.xml b/indra/newview/skins/default/xui/es/panel_edit_skin.xml
index 501ecfb4de..8d895a6152 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_skin.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skin_panel">
<panel name="avatar_skin_color_panel">
- <texture_picker label="Tatuajes de la cabeza" name="Head Tattoos" tool_tip="Pulsa para elegir una imagen"/>
- <texture_picker label="Tatuajes superiores" name="Upper Tattoos" tool_tip="Pulsa para elegir una imagen"/>
- <texture_picker label="Tatuajes inferiores" name="Lower Tattoos" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Cabeza" name="Head" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Parte superior del cuerpo" name="Upper Body" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Parte inferior del cuerpo" name="Lower Body" tool_tip="Pulsa para elegir una imagen"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/es/panel_nearby_chat.xml b/indra/newview/skins/default/xui/es/panel_nearby_chat.xml
index 5a852a6711..4220ab3c9f 100644
--- a/indra/newview/skins/default/xui/es/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/es/panel_nearby_chat.xml
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="nearby_chat">
- <check_box label="Traducir chat" name="translate_chat_checkbox"/>
+ <check_box label="Traducir el chat" name="translate_chat_checkbox"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_postcard_message.xml b/indra/newview/skins/default/xui/es/panel_postcard_message.xml
new file mode 100644
index 0000000000..7316d91f5c
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_postcard_message.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_message">
+ <text name="to_label">
+ Hasta:
+ </text>
+ <text name="name_label">
+ Desde:
+ </text>
+ <text name="subject_label">
+ Asunto:
+ </text>
+ <line_editor label="Escribe aquí el asunto." name="subject_form"/>
+ <text name="msg_label">
+ Mensaje:
+ </text>
+ <text_editor name="msg_form">
+ Escribe aquí tu mensaje.
+ </text_editor>
+ <button label="Cancelar" name="cancel_btn"/>
+ <button label="Enviar" name="send_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_postcard_settings.xml b/indra/newview/skins/default/xui/es/panel_postcard_settings.xml
new file mode 100644
index 0000000000..3931319447
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_postcard_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_settings">
+ <combo_box label="Resolución" name="postcard_size_combo">
+ <combo_box.item label="Ventana actual" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Personalizado" name="Custom"/>
+ </combo_box>
+ <layout_stack name="postcard_image_params_ls">
+ <layout_panel name="postcard_image_size_lp">
+ <spinner label="Ancho" name="postcard_snapshot_width"/>
+ <spinner label="Altura" name="postcard_snapshot_height"/>
+ <check_box label="Mantener las proporciones" name="postcard_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="postcard_image_format_quality_lp">
+ <slider label="Calidad de la imagen" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
index e822585566..aea9b9ce4a 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
@@ -29,30 +29,5 @@
<check_box label="Chats de MI" name="EnableIMChatPopups" tool_tip="Activa esta casilla para ver una ventana emergente cada vez que recibas un mensaje instantáneo"/>
<spinner label="Duración de los interlocutores favoritos:" name="nearby_toasts_lifetime"/>
<spinner label="Tiempo de los otros interlocutores:" name="nearby_toasts_fadingtime"/>
- <check_box name="translate_chat_checkbox"/>
- <text name="translate_chb_label">
- Usar en el chat el traductor automático
- </text>
- <text name="translate_language_text">
- Traducir el chat al:
- </text>
- <combo_box name="translate_language_combobox">
- <combo_box.item label="Predeterminado del sistema" name="System Default Language"/>
- <combo_box.item label="English (inglés)" name="English"/>
- <combo_box.item label="Dansk (danés)" name="Danish"/>
- <combo_box.item label="Deutsch (alemán)" name="German"/>
- <combo_box.item label="Español" name="Spanish"/>
- <combo_box.item label="Français (francés)" name="French"/>
- <combo_box.item label="Italiano (italiano)" name="Italian"/>
- <combo_box.item label="Magyar (húngaro)" name="Hungarian"/>
- <combo_box.item label="Nederlands (neerlandés)" name="Dutch"/>
- <combo_box.item label="Polski (polaco)" name="Polish"/>
- <combo_box.item label="Português (portugués)" name="Portugese"/>
- <combo_box.item label="Русский (ruso)" name="Russian"/>
- <combo_box.item label="Türkçe (turco)" name="Turkish"/>
- <combo_box.item label="Українська (ucraniano)" name="Ukrainian"/>
- <combo_box.item label="中文 (正體) (Chino)" name="Chinese"/>
- <combo_box.item label="日本語 (japonés)" name="Japanese"/>
- <combo_box.item label="한국어 (coreano)" name="Korean"/>
- </combo_box>
+ <button label="Configuración de la traducción del chat" name="ok_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
index 3de18654b5..81a29dae5a 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
@@ -15,7 +15,7 @@
Web:
</text>
<radio_group name="use_external_browser">
- <radio_item label="Usar mi navegador (IE, Firefox, Safari)" name="external" tool_tip="Usa tu navegador por defecto para ayuda, enlaces web, etc. No es aconsejable si estás a pantalla completa." value="1"/>
+ <radio_item label="Usar mi navegador (IE, Firefox, Safari)" name="external" tool_tip="Usa tu navegador por defecto para ayuda, enlaces web, etc. No es aconsejable si estás a pantalla completa." value="true"/>
<radio_item label="Usar el navegador incorporado" name="internal" tool_tip="Usa el navegador incorporado para ayuda, enlaces web, etc. Este navegador se abre en una nueva ventana dentro de [APP_NAME]." value=""/>
</radio_group>
<check_box initial_value="true" label="Activar plugins" name="browser_plugins_enabled"/>
diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml
new file mode 100644
index 0000000000..12c74b5cd1
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_inventory">
+ <text name="title">
+ Guardar en mi inventario
+ </text>
+ <text name="hint_lbl">
+ Guardar una imagen en el inventario cuesta [UPLOAD_COST] L$. Para guardar una imagen como una textura, selecciona uno de los formatos cuadrados.
+ </text>
+ <combo_box label="Resolución" name="texture_size_combo">
+ <combo_box.item label="Ventana actual" name="CurrentWindow"/>
+ <combo_box.item label="Pequeña (128x128)" name="Small(128x128)"/>
+ <combo_box.item label="Mediana (256x256)" name="Medium(256x256)"/>
+ <combo_box.item label="Grande (512x512)" name="Large(512x512)"/>
+ <combo_box.item label="Personalizado" name="Custom"/>
+ </combo_box>
+ <spinner label="Ancho" name="inventory_snapshot_width"/>
+ <spinner label="Altura" name="inventory_snapshot_height"/>
+ <check_box label="Mantener las proporciones" name="inventory_keep_aspect_check"/>
+ <button label="Cancelar" name="cancel_btn"/>
+ <button label="Guardar" name="save_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_local.xml b/indra/newview/skins/default/xui/es/panel_snapshot_local.xml
new file mode 100644
index 0000000000..08c45d2e76
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_snapshot_local.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_local">
+ <text name="title">
+ Guardar en mi ordenador
+ </text>
+ <combo_box label="Resolución" name="local_size_combo">
+ <combo_box.item label="Ventana actual" name="CurrentWindow"/>
+ <combo_box.item label="320x240" name="320x240"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="1280x1024" name="1280x1024"/>
+ <combo_box.item label="1600x1200" name="1600x1200"/>
+ <combo_box.item label="Personalizado" name="Custom"/>
+ </combo_box>
+ <layout_stack name="local_image_params_ls">
+ <layout_panel name="local_image_size_lp">
+ <spinner label="Ancho" name="local_snapshot_width"/>
+ <spinner label="Altura" name="local_snapshot_height"/>
+ <check_box label="Mantener las proporciones" name="local_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="local_image_format_quality_lp">
+ <combo_box label="Formato" name="local_format_combo">
+ <combo_box.item label="PNG (sin pérdida)" name="PNG"/>
+ <combo_box.item label="JPEG" name="JPEG"/>
+ <combo_box.item label="BMP (sin pérdida)" name="BMP"/>
+ </combo_box>
+ <slider label="Calidad de la imagen" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <button label="Cancelar" name="cancel_btn"/>
+ <flyout_button label="Guardar" name="save_btn" tool_tip="Guardar la imagen en un archivo">
+ <flyout_button.item label="Guardar" name="save_item"/>
+ <flyout_button.item label="Guardar como..." name="saveas_item"/>
+ </flyout_button>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_options.xml b/indra/newview/skins/default/xui/es/panel_snapshot_options.xml
new file mode 100644
index 0000000000..2b2584f66c
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_snapshot_options.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_options">
+ <button label="Publicar en los comentarios de Mi perfil" name="save_to_profile_btn"/>
+ <button label="Correo-e" name="save_to_email_btn"/>
+ <button label="Guardar en Mi inventario ([AMOUNT] L$)" name="save_to_inventory_btn"/>
+ <button label="Guardar en mi ordenador" name="save_to_computer_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml
new file mode 100644
index 0000000000..649d547ba0
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_postcard">
+ <string name="default_subject">
+ Postal desde [SECOND_LIFE].
+ </string>
+ <string name="default_message">
+ ¡Mira esto!
+ </string>
+ <string name="upload_message">
+ Enviando...
+ </string>
+ <text name="title">
+ Correo-e
+ </text>
+ <button label="Mensaje" name="message_btn"/>
+ <button label="Ajustes" name="settings_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/es/panel_snapshot_profile.xml
new file mode 100644
index 0000000000..6a0bc22d68
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_snapshot_profile.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_profile">
+ <text name="title">
+ Publicar en los comentarios de Mi perfil
+ </text>
+ <combo_box label="Resolución" name="profile_size_combo">
+ <combo_box.item label="Ventana actual" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Personalizado" name="Custom"/>
+ </combo_box>
+ <layout_stack name="profile_image_params_ls">
+ <layout_panel name="profile_image_size_lp">
+ <spinner label="Ancho" name="profile_snapshot_width"/>
+ <spinner label="Altura" name="profile_snapshot_height"/>
+ <check_box label="Mantener las proporciones" name="profile_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="profile_image_metadata_lp">
+ <text name="caption_label">
+ Título:
+ </text>
+ <check_box initial_value="true" label="Incluir ubicación" name="add_location_cb"/>
+ </layout_panel>
+ </layout_stack>
+ <button label="Cancelar" name="cancel_btn"/>
+ <button label="Publicar" name="post_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_status_bar.xml b/indra/newview/skins/default/xui/es/panel_status_bar.xml
index d43790c8c6..79b2c32b23 100644
--- a/indra/newview/skins/default/xui/es/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_status_bar.xml
@@ -18,7 +18,7 @@
<panel name="balance_bg">
<text name="balance" tool_tip="Haz clic para actualizar tu saldo en L$" value="20 L$"/>
<button label="Comprar L$" name="buyL" tool_tip="Pulsa para comprar más L$"/>
- <button label="Comprar" name="goShop" tool_tip="Abrir el mercado de Second Life"/>
+ <button label="Comprar" name="goShop" tool_tip="Abrir el mercado de Second Life" width="80"/>
</panel>
<text name="TimeText" tool_tip="Hora actual (Pacífico)">
24:00 AM PST
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index e3ea4baa6c..2a6f32f84f 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -1199,7 +1199,7 @@ Intenta iniciar sesión de nuevo en unos instantes.
No tienes en tu inventario una copia de esta textura
</string>
<string name="InventoryInboxNoItems">
- Aquí se entregarán los objetos comprados en el mercado.
+ Cuando compres un objeto o lo recibas por otra vía, aparecerá aquí, para que puedas arrastrarlo a una carpeta de tu inventario o eliminarlo si no deseas conservarlo.
</string>
<string name="MarketplaceURL">
http://marketplace.[DOMAIN_NAME]
@@ -1391,6 +1391,9 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="no_attachments">
No tienes puestos anexos
</string>
+ <string name="Attachments remain">
+ Anexos (quedan [COUNT] ranuras)
+ </string>
<string name="Buy">
Comprar
</string>
@@ -1517,6 +1520,12 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="Right Pec">
Pecho derecho
</string>
+ <string name="Neck">
+ Cuello
+ </string>
+ <string name="Avatar Center">
+ Centro del avatar
+ </string>
<string name="Invalid Attachment">
Punto de colocación no válido
</string>
@@ -3943,6 +3952,18 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
<string name="you_paid_ldollars_no_name">
Has pagado [AMOUNT] L$ por [REASON].
</string>
+ <string name="you_paid_failure_ldollars">
+ No has pagado a [NAME] [AMOUNT] L$ [REASON].
+ </string>
+ <string name="you_paid_failure_ldollars_no_info">
+ No has pagado [AMOUNT] L$.
+ </string>
+ <string name="you_paid_failure_ldollars_no_reason">
+ No has pagado a [NAME] [AMOUNT] L$.
+ </string>
+ <string name="you_paid_failure_ldollars_no_name">
+ No has pagado [AMOUNT] L$ [REASON].
+ </string>
<string name="for item">
para [ITEM]
</string>
@@ -4353,6 +4374,12 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="ExternalEditorFailedToRun">
Error al ejecutar el editor externo.
</string>
+ <string name="TranslationFailed">
+ Error al traducir: [REASON]
+ </string>
+ <string name="TranslationResponseParseError">
+ Error al analizar la respuesta de la traducción.
+ </string>
<string name="Esc">
Esc
</string>
@@ -4723,7 +4750,7 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
Minimapa
</string>
<string name="Command_Move_Label">
- Moverme
+ Caminar / Correr / Volar
</string>
<string name="Command_People_Label">
Gente
@@ -4750,10 +4777,10 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
Hablar
</string>
<string name="Command_View_Label">
- Visión
+ Controles de la cámara
</string>
<string name="Command_Voice_Label">
- Chat de voz
+ Configuración de voz
</string>
<string name="Command_AboutLand_Tooltip">
Información sobre el terreno que vas a visitar
@@ -4825,7 +4852,16 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
Cambiando el ángulo de la cámara
</string>
<string name="Command_Voice_Tooltip">
- Personas próximas con capacidad de voz
+ Controles de volumen para las llamadas y la gente que se encuentre cerca de ti en el mundo virtual
+ </string>
+ <string name="Toolbar_Bottom_Tooltip">
+ actualmente en tu barra de herramientas inferior
+ </string>
+ <string name="Toolbar_Left_Tooltip">
+ actualmente en tu barra de herramientas izquierda
+ </string>
+ <string name="Toolbar_Right_Tooltip">
+ actualmente en tu barra de herramientas derecha
</string>
<string name="Retain%">
% retención
@@ -4851,4 +4887,19 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="Normal">
Normal
</string>
+ <string name="snapshot_quality_very_low">
+ Muy bajo
+ </string>
+ <string name="snapshot_quality_low">
+ Bajo
+ </string>
+ <string name="snapshot_quality_medium">
+ Medio
+ </string>
+ <string name="snapshot_quality_high">
+ Alto
+ </string>
+ <string name="snapshot_quality_very_high">
+ Muy alto
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/es/teleport_strings.xml b/indra/newview/skins/default/xui/es/teleport_strings.xml
index e785a7ac40..a23d9c43d0 100644
--- a/indra/newview/skins/default/xui/es/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/es/teleport_strings.xml
@@ -20,8 +20,8 @@ Si sigues recibiendo este mensaje, por favor, acude al [SUPPORT_SITE].
Vuelva a intentarlo en un momento.
</message>
<message name="NoHelpIslandTP">
- No puede teleportarse de vuelta a la Welcome Island (&apos;Isla de Ayuda&apos;).
-Vaya a la &apos;Welcome Island Public&apos; (&apos;Isla Pública de Ayuda&apos;) para repetir el tutorial.
+ No te puedes volver a teleportar a la isla de bienvenida.
+Para repetir el tutorial, visita la isla de bienvenida pública.
</message>
<message name="noaccess_tport">
Lo sentimos, pero no tienes acceso al destino de este teleporte.
diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml
index 4d02513a53..4409949584 100644
--- a/indra/newview/skins/default/xui/fr/floater_about.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about.xml
@@ -67,32 +67,34 @@ Version serveur vocal : [VOICE_VERSION]
<panel label="Licences" name="licenses_panel">
<text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
-APR Copyright (C) 2000-2004 The Apache Software Foundation
-Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
-cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
-DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
-expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
-FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
-GL Copyright (C) 1999-2004 Brian Paul.
-GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University et David Luebke, Brenden Schubert, University of Virginia.
-google-perftools Copyright (c) 2005, Google Inc.
-Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
-jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
-jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
-ogg/vorbis Copyright (C) 2001, Xiphophorus
-OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
-PCRE Copyright (c) 1997-2008 University of Cambridge
-SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
-SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
-zlib Copyright (C) 1995-2002 Jean-loup Gailly et Mark Adler.
-google-perftools Copyright (c) 2005, Google Inc.
+ APR Copyright (C) 2000-2004 The Apache Software Foundation
+ Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
+ expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+ FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ GL Copyright (C) 1999-2004 Brian Paul.
+ GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University et David Luebke, Brenden Schubert, University of Virginia.
+ google-perftools Copyright (c) 2005, Google Inc.
+ Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
+ jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
+ jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
+ ogg/vorbis Copyright (C) 2001, Xiphophorus
+ OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2008 University of Cambridge
+ SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+ SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
+ zlib Copyright (C) 1995-2002 Jean-loup Gailly et Mark Adler.
+ google-perftools Copyright (c) 2005, Google Inc.
-Le client Second Life utilise Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (et ses concédants de licence). Tous droits réservés. Pour plus de détails, consultez le site Web www.havok.com.
+ Le client Second Life utilise Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (et ses concédants de licence). Tous droits réservés. Pour plus de détails, consultez le site Web www.havok.com.
-Tous droits réservés. Voir licenses.txt pour plus d&apos;informations.
+ Ce logiciel contient du code source fourni par NVIDIA Corporation.
-Codage audio du chat vocal : Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
+ Tous droits réservés. Voir licenses.txt pour plus d&apos;informations.
+
+ Codage audio du chat vocal : Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
</text_editor>
</panel>
</tab_container>
diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml
index 9771c3f7fd..b554a0a892 100644
--- a/indra/newview/skins/default/xui/fr/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml
@@ -132,7 +132,7 @@
Trafic :
</text>
<text name="DwellText">
- 0
+ Chargement...
</text>
<button label="Acheter du terrain" label_selected="Acheter le terrain..." left_delta="60" name="Buy Land..." width="125"/>
<button label="Vente Linden" label_selected="Vente Linden..." name="Linden Sale..." tool_tip="Le terrain doit être la propriété d&apos;un résident, avoir un contenu défini et ne pas être aux enchères."/>
@@ -313,13 +313,15 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche.
Pas de bousculades (les règles de la région priment)
</panel.string>
<panel.string name="see_avs_text">
- Voir et chatter avec les résidents sur cette parcelle
+ Les avatars sur les autres parcelles peuvent voir
</panel.string>
<text name="allow_label">
Autoriser les autres résidents à :
</text>
- <check_box label="Modifier le terrain" name="edit land check" tool_tip="Si cette option est cochée, n&apos;importe qui peut terraformer votre terrain. Il vaut mieux ne pas cocher cette option pour toujours pouvoir modifer votre propre terrain."/>
- <check_box label="Voler" name="check fly" tool_tip="Si cette option est cochée, les résidents peuvent voler sur votre terrain. Si elle n&apos;est pas cochée, ils ne pourront voler que lorsqu&apos;ils arrivent et passent au dessus de votre terrain."/>
+ <text name="allow_label0">
+ Voler :
+ </text>
+ <check_box label="Tous" name="check fly" tool_tip="Si cette option est cochée, les résidents peuvent voler sur votre terrain. Si elle n&apos;est pas cochée, ils ne pourront voler que lorsqu&apos;ils arrivent et passent au dessus de votre terrain."/>
<text name="allow_label2">
Construire :
</text>
@@ -335,9 +337,6 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche.
</text>
<check_box label="Tous" name="check other scripts"/>
<check_box label="Groupe" name="check group scripts"/>
- <text name="land_options_label">
- Options du terrain :
- </text>
<check_box label="Sécurisé (pas de dégâts)" name="check safe" tool_tip="Si cette option est cochée, le terrain est sécurisé et il n&apos;y pas de risques de dommages causés par des combats. Si elle est décochée, des dommages causés par les combats peuvent avoir lieu."/>
<check_box label="Pas de bousculades" name="PushRestrictCheck" tool_tip="Empêche l&apos;utilisation de scripts causant des bousculades. Cette option est utile pour empêcher les comportements abusifs sur votre terrain."/>
<check_box label="Afficher le lieu dans la recherche (30 L$/semaine)" name="ShowDirectoryCheck" tool_tip="Afficher la parcelle dans les résultats de recherche"/>
@@ -378,9 +377,9 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche.
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Cliquez pour sélectionner une image"/>
<text name="allow_label5">
- Autoriser les résidents sur les autres parcelles à :
+ et chatter avec les avatars sur cette parcelle
</text>
- <check_box label="Voir les avatars" name="SeeAvatarsCheck" tool_tip="Permettre aux résidents présents sur d&apos;autres parcelles de voir et chatter avec les résidents présents sur cette parcelle et vous permettre de les voir et de chatter avec eux."/>
+ <check_box label="Voir les avatars" name="SeeAvatarsCheck" tool_tip="Permettre aux avatars présents sur d&apos;autres parcelles de voir et chatter avec les avatars présents sur cette parcelle et à vous de les voir et de chatter avec eux."/>
<text name="landing_point">
Lieu d&apos;arrivée : [LANDING]
</text>
diff --git a/indra/newview/skins/default/xui/fr/floater_avatar.xml b/indra/newview/skins/default/xui/fr/floater_avatar.xml
index cfbac66c0e..7cbb50a3d6 100644
--- a/indra/newview/skins/default/xui/fr/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/fr/floater_avatar.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Avatar" title="CHOIX D&apos;AVATAR"/>
+<floater name="Avatar" title="CHOISIR UN AVATAR"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
index d9e8e8821d..148a5a35d2 100644
--- a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
@@ -22,10 +22,10 @@ le Lindex...
<text name="currency_action">
Je veux acheter
</text>
- <text name="currency_label" left="308">
+ <text left="308" name="currency_label">
L$
</text>
- <line_editor label="L$" name="currency_amt" width="65" left_pad="-85">
+ <line_editor label="L$" left_pad="-85" name="currency_amt" width="65">
1234
</line_editor>
<text name="buying_label">
@@ -47,13 +47,13 @@ le Lindex...
[AMT] L$
</text>
<text name="currency_links">
- [http://www.secondlife.com/my/account/payment_method_management.php?lang=fr-FR mode de paiement] | [http://www.secondlife.com/my/account/currency.php?lang=fr-FR devise]
+ [http://www.secondlife.com/my/account/payment_method_management.php mode de paiement] | [http://www.secondlife.com/my/account/currency.php devise]
</text>
<text name="exchange_rate_note">
Saisissez à nouveau le montant pour voir le taux de change actuel.
</text>
<text name="purchase_warning_repurchase">
- Confirmer cet achat n'achète que des L$, pas l'objet.
+ Confirmer cet achat n&apos;achète que des L$, pas l&apos;objet.
</text>
<text bottom_delta="16" name="purchase_warning_notenough">
Vous n&apos;achetez pas assez de L$. Veuillez augmenter le montant.
diff --git a/indra/newview/skins/default/xui/fr/floater_camera.xml b/indra/newview/skins/default/xui/fr/floater_camera.xml
index 77d3c2cfe4..f2b0ee8af3 100644
--- a/indra/newview/skins/default/xui/fr/floater_camera.xml
+++ b/indra/newview/skins/default/xui/fr/floater_camera.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="camera_floater" title="AFFICHER">
+<floater name="camera_floater" title="PARAMÈTRES DE LA CAMÉRA">
<floater.string name="rotate_tooltip">
Faire tourner la caméra autour du point central
</floater.string>
diff --git a/indra/newview/skins/default/xui/fr/floater_chat_bar.xml b/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
index 88a2fb669b..c7d27c0589 100644
--- a/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="chat_bar" title="CHAT PRÈS DE MOI">
- <panel>
+ <panel name="bottom_panel">
<line_editor label="Cliquer ici pour chatter." name="chat_box" tool_tip="Appuyer sur Entrée pour dire, Ctrl-Entrée pour crier"/>
<button name="show_nearby_chat" tool_tip="Affiche/Masque le journal de chats près de vous"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml b/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
index 8ad301823b..2bc76e0c63 100644
--- a/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
@@ -4,7 +4,7 @@
Filtres :
</text>
<check_box label="Filtre anisotrope (plus lent si activé)" name="ani"/>
- <text name="Antialiasing:">
+ <text name="antialiasing label">
Anti-aliasing :
</text>
<combo_box label="Anti-aliasing" name="fsaa" width="84">
diff --git a/indra/newview/skins/default/xui/fr/floater_model_preview.xml b/indra/newview/skins/default/xui/fr/floater_model_preview.xml
index a26deb1aef..a3b50351ae 100644
--- a/indra/newview/skins/default/xui/fr/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_model_preview.xml
@@ -4,6 +4,9 @@
<string name="status_parse_error">
Erreur : Problème d&apos;analyse de fichier .dae ; reportez-vous au journal pour plus de détails.
</string>
+ <string name="status_material_mismatch">
+ Erreur : le matériau du modèle ne correspond pas à un sous-ensemble du modèle de référence.
+ </string>
<string name="status_reading_file">
Chargement...
</string>
@@ -137,7 +140,7 @@
</panel>
<panel name="physics analysis">
<text name="method_label">
- Étape 2 : Analyse
+ Étape 2 : Analyser
</text>
<text name="analysis_method_label">
Moyen :
diff --git a/indra/newview/skins/default/xui/fr/floater_model_wizard.xml b/indra/newview/skins/default/xui/fr/floater_model_wizard.xml
index cd2eb761ec..63feb1d403 100644
--- a/indra/newview/skins/default/xui/fr/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/fr/floater_model_wizard.xml
@@ -20,6 +20,9 @@
Choisir un fichier de modèle à charger
</text>
<button label="Parcourir..." label_selected="Parcourir..." name="browse"/>
+ <text name="Model types">
+ Second Life prend en charge les fichiers COLLADA (.dae).
+ </text>
<text name="dimensions">
X Y Z
</text>
diff --git a/indra/newview/skins/default/xui/fr/floater_moveview.xml b/indra/newview/skins/default/xui/fr/floater_moveview.xml
index 0b0ec51846..853af2afdf 100644
--- a/indra/newview/skins/default/xui/fr/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_moveview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="move_floater" title="BOUGER">
+<floater name="move_floater" title="MARCHER / COURIR / VOLER">
<string name="walk_forward_tooltip">
Marcher en avant (appuyer sur la flèche vers le haut ou W)
</string>
diff --git a/indra/newview/skins/default/xui/fr/floater_snapshot.xml b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
index 365ff77ff9..9244051edc 100644
--- a/indra/newview/skins/default/xui/fr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
@@ -3,73 +3,63 @@
<floater.string name="unknown">
inconnu
</floater.string>
- <radio_group label="Type de photo" name="snapshot_type_radio">
- <radio_item label="E-mail" name="postcard"/>
- <radio_item label="Mon inventaire ([AMOUNT] L$)" name="texture"/>
- <radio_item label="Enregistrer sur mon ordinateur" name="local"/>
- </radio_group>
+ <string name="postcard_progress_str">
+ Envoi par e-mail
+ </string>
+ <string name="profile_progress_str">
+ Publication
+ </string>
+ <string name="inventory_progress_str">
+ Enregistrement dans l&apos;inventaire
+ </string>
+ <string name="local_progress_str">
+ Enregistrement sur l&apos;ordinateur
+ </string>
+ <string name="profile_succeeded_str">
+ Image chargée
+ </string>
+ <string name="postcard_succeeded_str">
+ Envoi par e-mail effectué !
+ </string>
+ <string name="inventory_succeeded_str">
+ Enregistrement dans l&apos;inventaire effectué !
+ </string>
+ <string name="local_succeeded_str">
+ Enregistrement sur l&apos;ordinateur effectué !
+ </string>
+ <string name="profile_failed_str">
+ Échec de chargement de l&apos;image sur le flux de votre profil.
+ </string>
+ <string name="postcard_failed_str">
+ Échec d&apos;envoi par e-mail.
+ </string>
+ <string name="inventory_failed_str">
+ Échec d&apos;enregistrement dans l&apos;inventaire.
+ </string>
+ <string name="local_failed_str">
+ Échec d&apos;enregistrement sur l&apos;ordinateur.
+ </string>
+ <button name="advanced_options_btn" tool_tip="Options avancées"/>
+ <text name="image_res_text">
+ [WIDTH] x [HEIGHT] px
+ </text>
<text name="file_size_label">
[SIZE] Ko
</text>
- <button label="Rafraîchir" name="new_snapshot_btn"/>
- <button label="Envoyer" name="send_btn"/>
- <button label="Enreg. ([AMOUNT] L$)" name="upload_btn"/>
- <flyout_button label="Enregistrer" name="save_btn" tool_tip="Enregistrer l&apos;image sous forme de fichier">
- <flyout_button.item label="Enregistrer" name="save_item"/>
- <flyout_button.item label="Enregistrer sous..." name="saveas_item"/>
- </flyout_button>
- <button label="Plus" name="more_btn" tool_tip="Options avancées"/>
- <button label="Moins" name="less_btn" tool_tip="Options avancées"/>
- <button label="Annuler" name="discard_btn"/>
- <text name="type_label2">
- Taille
- </text>
- <text name="format_label">
- Format
- </text>
- <combo_box label="Résolution" name="postcard_size_combo">
- <combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
- <combo_box.item label="640 x 480" name="640x480"/>
- <combo_box.item label="800 x 600" name="800x600"/>
- <combo_box.item label="1 024 x 768" name="1024x768"/>
- <combo_box.item label="Personnalisée" name="Custom"/>
- </combo_box>
- <combo_box label="Résolution" name="texture_size_combo">
- <combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
- <combo_box.item label="Petite (128 x 128)" name="Small(128x128)"/>
- <combo_box.item label="Moyenne (256 x 256)" name="Medium(256x256)"/>
- <combo_box.item label="Grande (512 x 512)" name="Large(512x512)"/>
- <combo_box.item label="Personnalisée" name="Custom"/>
- </combo_box>
- <combo_box label="Résolution" name="local_size_combo">
- <combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
- <combo_box.item label="320 x 240" name="320x240"/>
- <combo_box.item label="640 x 480" name="640x480"/>
- <combo_box.item label="800 x 600" name="800x600"/>
- <combo_box.item label="1 024 x 768" name="1024x768"/>
- <combo_box.item label="1 280 x 1 024" name="1280x1024"/>
- <combo_box.item label="1 600 x 1 200" name="1600x1200"/>
- <combo_box.item label="Personnalisée" name="Custom"/>
- </combo_box>
- <combo_box label="Format" name="local_format_combo">
- <combo_box.item label="PNG" name="PNG"/>
- <combo_box.item label="JPEG" name="JPEG"/>
- <combo_box.item label="BMP" name="BMP"/>
- </combo_box>
- <spinner label="Larg." name="snapshot_width"/>
- <spinner label="Haut." name="snapshot_height"/>
- <check_box label="Contraindre les proportions" name="keep_aspect_check"/>
- <slider label="Qualité de l&apos;image" name="image_quality_slider"/>
- <text name="layer_type_label">
- Capturer :
- </text>
- <combo_box label="Couches d&apos;images" name="layer_types">
- <combo_box.item label="Couleurs" name="Colors"/>
- <combo_box.item label="Profondeur" name="Depth"/>
- </combo_box>
- <check_box label="Interface" name="ui_check"/>
- <check_box label="HUD" name="hud_check"/>
- <check_box label="Garder ouvert après enregistrement" name="keep_open_check"/>
- <check_box label="Arrêt sur image (plein écran)" name="freeze_frame_check"/>
- <check_box label="Actualisation automatique" name="auto_snapshot_check"/>
+ <panel name="advanced_options_panel">
+ <text name="advanced_options_label">
+ OPTIONS AVANCÉES
+ </text>
+ <text name="layer_type_label">
+ Capturer :
+ </text>
+ <combo_box label="Couches d&apos;images" name="layer_types">
+ <combo_box.item label="Couleurs" name="Colors"/>
+ <combo_box.item label="Profondeur" name="Depth"/>
+ </combo_box>
+ <check_box label="Interface" name="ui_check"/>
+ <check_box label="HUD" name="hud_check"/>
+ <check_box label="Arrêt sur image (plein écran)" name="freeze_frame_check"/>
+ <check_box label="Actualisation automatique" name="auto_snapshot_check"/>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_toybox.xml b/indra/newview/skins/default/xui/fr/floater_toybox.xml
index 33aea6bb2d..f99d3d30b5 100644
--- a/indra/newview/skins/default/xui/fr/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/fr/floater_toybox.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Toybox" title="PERSONNALISER LES BARRES D&apos;OUTILS">
+<floater name="Toybox" title="BOUTONS DES BARRES D&apos;OUTILS">
<text name="toybox label 1">
Ajouter ou supprimer des boutons : les faire glisser vers ou depuis les barres d&apos;outils.
</text>
<text name="toybox label 2">
Ils s&apos;afficheront comme indiqué ou comme des icônes, selon les paramètres de barre d&apos;outils.
</text>
+ <button label="Effacer tout" label_selected="Effacer tout" name="btn_clear_all"/>
<button label="Valeurs par défaut" label_selected="Valeurs par défaut" name="btn_restore_defaults"/>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_translation_settings.xml b/indra/newview/skins/default/xui/fr/floater_translation_settings.xml
new file mode 100644
index 0000000000..c7582f110f
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_translation_settings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_translation_settings" title="TRADUCTION AUTOMATIQUE">
+ <string name="bing_api_key_not_verified">
+ ID d&apos;application Bing non vérifié. Veuillez réessayer.
+ </string>
+ <string name="google_api_key_not_verified">
+ Clé d&apos;API Google non vérifiée. Veuillez réessayer.
+ </string>
+ <string name="bing_api_key_verified">
+ ID d&apos;application Bing vérifié.
+ </string>
+ <string name="google_api_key_verified">
+ Clé d&apos;API Google vérifiée.
+ </string>
+ <check_box label="Activer la traduction automatique lors des chats" name="translate_chat_checkbox"/>
+ <text name="translate_language_label">
+ Traduire les chats en :
+ </text>
+ <combo_box name="translate_language_combo">
+ <combo_box.item label="Langue système par défaut" name="System Default Language"/>
+ <combo_box.item label="English (Anglais)" name="English"/>
+ <combo_box.item label="Dansk (Danois)" name="Danish"/>
+ <combo_box.item label="Deutsch (Allemand)" name="German"/>
+ <combo_box.item label="Español (Espagnol)" name="Spanish"/>
+ <combo_box.item label="Français" name="French"/>
+ <combo_box.item label="Italiano (Italien)" name="Italian"/>
+ <combo_box.item label="Magyar (Hongrois)" name="Hungarian"/>
+ <combo_box.item label="Nederlands (Néerlandais)" name="Dutch"/>
+ <combo_box.item label="Polski (Polonais)" name="Polish"/>
+ <combo_box.item label="Português (Portugais)" name="Portugese"/>
+ <combo_box.item label="Русский (Russe)" name="Russian"/>
+ <combo_box.item label="Türkçe (Turc)" name="Turkish"/>
+ <combo_box.item label="Українська (Ukrainien)" name="Ukrainian"/>
+ <combo_box.item label="中文 (正體) (Chinois)" name="Chinese"/>
+ <combo_box.item label="日本語 (Japonais)" name="Japanese"/>
+ <combo_box.item label="한국어 (Coréen)" name="Korean"/>
+ </combo_box>
+ <text name="tip">
+ Choisir le service à utiliser :
+ </text>
+ <radio_group name="translation_service_rg">
+ <radio_item initial_value="bing" label="Bing Translator" name="bing"/>
+ <radio_item initial_value="google" label="Google Translate" name="google"/>
+ </radio_group>
+ <text name="bing_api_key_label">
+ [http://www.bing.com/developers/createapp.aspx ID d&apos;application] Bing :
+ </text>
+ <button label="Vérifier" name="verify_bing_api_key_btn"/>
+ <text name="google_api_key_label">
+ [http://code.google.com/apis/language/translate/v2/getting_started.html#auth Clé d&apos;API] Google :
+ </text>
+ <button label="Vérifier" name="verify_google_api_key_btn"/>
+ <text name="google_links_text">
+ [http://code.google.com/apis/language/translate/v2/pricing.html Tarification] | [https://code.google.com/apis/console Statistiques]
+ </text>
+ <button label="OK" name="ok_btn"/>
+ <button label="Annuler" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_voice_controls.xml b/indra/newview/skins/default/xui/fr/floater_voice_controls.xml
index 2b2bb8bbe3..fc4de4a5a6 100644
--- a/indra/newview/skins/default/xui/fr/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/fr/floater_voice_controls.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_voice_controls" title="CONTROLES DE LA VOIX">
<string name="title_nearby">
- Chat près de vous
+ PARAMÈTRES VOCAUX
</string>
<string name="title_group">
- Appel de groupe avec [GROUP]
+ APPEL DE GROUPE AVEC [GROUP]
</string>
<string name="title_adhoc">
- Téléconférence
+ CONFÉRENCE
</string>
<string name="title_peer_2_peer">
- Appel avec [NAME]
+ APPEL AVEC [NAME]
</string>
<string name="no_one_near">
Il n&apos;y a personne près de vous avec le chat vocal activé
diff --git a/indra/newview/skins/default/xui/fr/menu_toolbars.xml b/indra/newview/skins/default/xui/fr/menu_toolbars.xml
index d3e9f92770..f74d206d56 100644
--- a/indra/newview/skins/default/xui/fr/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/fr/menu_toolbars.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Toolbars Popup">
- <menu_item_call label="Choisir les boutons..." name="Chose Buttons"/>
+ <menu_item_call label="Supprimer ce bouton" name="Remove button"/>
+ <menu_item_call label="Boutons des barres d&apos;outils..." name="Choose Buttons"/>
<menu_item_check label="Icônes et libellés" name="icons_with_text"/>
<menu_item_check label="Icônes uniquement" name="icons_only"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index d3b48639e0..9303815c30 100644
--- a/indra/newview/skins/default/xui/fr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu_bar name="Main Menu">
<menu label="Moi" name="Me">
- <menu_item_call label="Page d&apos;accueil..." name="Manage My Account">
- <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=fr"/>
- </menu_item_call>
<menu_item_call label="Profil..." name="Profile"/>
<menu_item_call label="Apparence..." name="ChangeOutfit"/>
+ <menu_item_call label="Choisir un avatar..." name="Avatar Picker"/>
<menu_item_check label="Inventaire..." name="Inventory"/>
- <menu_item_check label="Gestes..." name="Gestures"/>
- <menu_item_check label="Chat vocal..." name="ShowVoice"/>
+ <menu_item_call label="Nouvelle fenêtre d&apos;inventaire" name="NewInventoryWindow"/>
+ <menu_item_call label="Endroits..." name="Places"/>
+ <menu_item_call label="Favoris..." name="Picks"/>
+ <menu_item_call label="Paramètres de la caméra..." name="Camera Controls"/>
<menu label="Déplacement" name="Movement">
<menu_item_call label="M&apos;asseoir" name="Sit Down Here"/>
<menu_item_check label="Voler" name="Fly"/>
@@ -22,34 +22,39 @@
<menu_item_call label="Demander le statut Admin" name="Request Admin Options"/>
<menu_item_call label="Quitter le statut Admin" name="Leave Admin Options"/>
<menu_item_call label="Acheter des L$" name="Buy and Sell L$"/>
+ <menu_item_call label="Page d&apos;accueil du compte..." name="Manage My Account">
+ <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=fr"/>
+ </menu_item_call>
<menu_item_call label="Préférences..." name="Preferences"/>
- <menu_item_call label="Barres d&apos;outils..." name="Toolbars"/>
+ <menu_item_call label="Boutons des barres d&apos;outils..." name="Toolbars"/>
<menu_item_call label="Masquer tous les contrôles" name="Hide UI"/>
<menu_item_call label="Quitter [APP_NAME]" name="Quit"/>
</menu>
<menu label="Communiquer" name="Communicate">
- <menu_item_call label="Mes amis" name="My Friends"/>
- <menu_item_call label="Mes groupes" name="My Groups"/>
- <menu_item_check label="Chat près de moi" name="Nearby Chat"/>
- <menu_item_call label="Personnes près de moi" name="Active Speakers"/>
- <menu_item_check label="Chat vocal près de vous" name="Nearby Voice"/>
+ <menu_item_check label="Chat..." name="Nearby Chat"/>
+ <menu_item_check label="Parler" name="Speak"/>
+ <menu_item_check label="Paramètres vocaux..." name="Nearby Voice"/>
+ <menu_item_check label="Effet de voix..." name="ShowVoice"/>
+ <menu_item_check label="Gestes..." name="Gestures"/>
+ <menu_item_call label="Amis" name="My Friends"/>
+ <menu_item_call label="Groupes" name="My Groups"/>
+ <menu_item_call label="Personnes près de vous" name="Active Speakers"/>
</menu>
<menu label="Monde" name="World">
- <menu_item_check label="Mini-carte" name="Mini-Map"/>
+ <menu_item_call label="Créer un repère pour ce lieu" name="Create Landmark Here"/>
+ <menu_item_call label="Destinations..." name="Destinations"/>
<menu_item_check label="Carte du monde" name="World Map"/>
+ <menu_item_check label="Mini-carte" name="Mini-Map"/>
<menu_item_check label="Rechercher" name="Search"/>
+ <menu_item_call label="Me téléporter chez moi" name="Teleport Home"/>
+ <menu_item_call label="Définir le domicile ici" name="Set Home to Here"/>
<menu_item_call label="Photo" name="Take Snapshot"/>
- <menu_item_call label="Créer un repère pour ce lieu" name="Create Landmark Here"/>
- <menu label="Profil du lieu" name="Land">
- <menu_item_call label="Profil du lieu" name="Place Profile"/>
- <menu_item_call label="À propos du terrain" name="About Land"/>
- <menu_item_call label="Région/Domaine" name="Region/Estate"/>
- </menu>
+ <menu_item_call label="Profil du lieu" name="Place Profile"/>
+ <menu_item_call label="À propos du terrain" name="About Land"/>
+ <menu_item_call label="Région/Domaine" name="Region/Estate"/>
+ <menu_item_call label="Mes terrains..." name="My Land"/>
<menu_item_call label="Acheter ce terrain" name="Buy Land"/>
- <menu_item_call label="Mes terrains" name="My Land"/>
<menu label="Afficher" name="LandShow">
- <menu_item_check label="Contrôles de mouvement" name="Movement Controls"/>
- <menu_item_check label="Contrôles d’affichage" name="Camera Controls"/>
<menu_item_check label="Lignes d&apos;interdiction" name="Ban Lines"/>
<menu_item_check label="Balises" name="beacons"/>
<menu_item_check label="Limites du terrain" name="Property Lines"/>
@@ -58,16 +63,15 @@
<menu_item_check label="Propriétés de la parcelle" name="Parcel Properties"/>
<menu_item_check label="Menu Avancé" name="Show Advanced Menu"/>
</menu>
- <menu_item_call label="Me téléporter chez moi" name="Teleport Home"/>
- <menu_item_call label="Définir le domicile ici" name="Set Home to Here"/>
<menu label="Luminosité" name="Environment Settings">
<menu_item_call label="Aube" name="Sunrise"/>
<menu_item_call label="Milieu de journée" name="Noon"/>
<menu_item_call label="Coucher de soleil" name="Sunset"/>
<menu_item_call label="Minuit" name="Midnight"/>
+ <menu_item_call label="Utiliser les réglages de la région" name="Use Region Settings"/>
</menu>
- <menu label="Éditeur d&apos;environnement" name="Enviroment Editor">
- <menu_item_call label="Paramètres d&apos;environnement..." name="Enviroment Settings"/>
+ <menu label="Éditeur d&apos;environnement" name="Environment Editor">
+ <menu_item_call label="Paramètres d&apos;environnement..." name="Environment Settings"/>
<menu label="Préréglages de l&apos;eau" name="Water Presets">
<menu_item_call label="Nouveau préréglage..." name="new_water_preset"/>
<menu_item_call label="Modifier un préréglage..." name="edit_water_preset"/>
@@ -146,6 +150,7 @@
<menu_item_call label="Refaire" name="Redo"/>
</menu>
<menu label="Aide" name="Help">
+ <menu_item_call label="Aide rapide..." name="How To"/>
<menu_item_call label="Aide de [SECOND_LIFE]" name="Second Life Help"/>
<menu_item_call label="Signaler une infraction" name="Report Abuse"/>
<menu_item_call label="Signaler un bug" name="Report Bug"/>
@@ -200,11 +205,10 @@
<menu_item_check label="Utiliser le thread de lecture de plug-in" name="Use Plugin Read Thread"/>
<menu_item_call label="Effacer le cache du groupe" name="ClearGroupCache"/>
<menu_item_check label="Effet de lissage de la souris" name="Mouse Smoothing"/>
+ <menu_item_call label="Libérer les touches" name="Release Keys"/>
<menu label="Raccourcis" name="Shortcuts">
<menu_item_call label="Image ([COST] L$)..." name="Upload Image"/>
<menu_item_check label="Rechercher" name="Search"/>
- <menu_item_call label="Relâcher les touches" name="Release Keys"/>
- <menu_item_call label="Taille de l&apos;interface par défaut" name="Set UI Size to Default"/>
<menu_item_check label="Afficher le menu Avancé - raccourci existant" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="Fermer la fenêtre" name="Close Window"/>
<menu_item_call label="Fermer toutes les fenêtres" name="Close All Windows"/>
@@ -290,6 +294,7 @@
<menu_item_check label="Lumières" name="Lights"/>
<menu_item_check label="Squelette de collision" name="Collision Skeleton"/>
<menu_item_check label="Rayons" name="Raycast"/>
+ <menu_item_check label="Vecteurs de vent" name="Wind Vectors"/>
<menu_item_check label="Complexité du rendu" name="rendercomplexity"/>
<menu_item_check label="Sculpture" name="Sculpt"/>
</menu>
@@ -302,7 +307,6 @@
<menu_item_check label="Éclairage et ombres" name="Lighting and Shadows"/>
<menu_item_check label="Ombres du soleil/de la lune/des projecteurs" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO et lissage des ombres" name="SSAO and Shadow Smoothing"/>
- <menu_item_check label="Illumination globale (expérimental)" name="Global Illumination"/>
<menu_item_check label="Débogage GL" name="Debug GL"/>
<menu_item_check label="Débogage pipeline" name="Debug Pipeline"/>
<menu_item_check label="Masques alpha automatiques (différés)" name="Automatic Alpha Masks (deferred)"/>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index d8d79d8dde..2f9bf23bc4 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -980,7 +980,7 @@ Proposer à [NAME] de devenir votre ami(e) ?
</form>
</notification>
<notification name="RemoveFromFriends">
- Voulez-vous supprimer &lt;nolink&gt;[NAME]&lt;/nolink&gt; de votre liste d&apos;amis ?
+ Voulez-vous supprimer &lt;nolink&gt;[NAME]&lt;/nolink&gt; de votre liste d&apos;amis ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="RemoveMultipleFromFriends">
@@ -1105,8 +1105,13 @@ Céder ces [AREA] m² de terrain au groupe [GROUP_NAME] ?
<notification name="DisplaySetToSafe">
Les paramètres d&apos;affichage sont au niveau le plus sûr, comme vous l&apos;aviez indiqué.
</notification>
- <notification name="DisplaySetToRecommended">
- Vos paramètres d&apos;affichage ont été réglés avec une marge de sécurité en fonction de votre configuration système.
+ <notification name="DisplaySetToRecommendedGPUChange">
+ Les paramètres d&apos;affichage ont été modifiés selon les niveaux recommandés car votre carte graphique
+[LAST_GPU] a été remplacée
+par une carte [THIS_GPU].
+ </notification>
+ <notification name="DisplaySetToRecommendedFeatureChange">
+ Les paramètres d&apos;affichage ont été modifiés selon les niveaux recommandés en raison d&apos;un changement relatif au sous-système de rendu.
</notification>
<notification name="ErrorMessage">
[ERROR_MESSAGE]
@@ -1428,7 +1433,7 @@ Version [VERSION]
<usetemplate ignoretext="Confirmer avant de rendre les objets à leurs propriétaires" name="okcancelignore" notext="Annuler" yestext="OK"/>
</notification>
<notification name="GroupLeaveConfirmMember">
- Vous êtes actuellement membre du groupe [GROUP].
+ Vous êtes actuellement membre du groupe &lt;nolink&gt;[GROUP]&lt;/nolink&gt;.
Quitter le groupe ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
@@ -1910,9 +1915,15 @@ Déplacer les objets de l&apos;inventaire ?
<usetemplate ignoretext="Confirmer avant de quitter" name="okcancelignore" notext="Ne pas quitter" yestext="Quitter"/>
</notification>
<notification name="ConfirmRestoreToybox">
- Etes-vous certain de vouloir restaurer vos boutons et barres d&apos;outils par défaut ?
+ Cette action rétablira vos boutons et barres d&apos;outils par défaut.
+
+Vous ne pouvez pas l&apos;annuler.
+ <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
+ </notification>
+ <notification name="ConfirmClearAllToybox">
+ Cette action replacera tous les boutons dans la boîte à outils de sorte que vos barres d&apos;outils seront vides.
-Vous ne pouvez pas annuler cette action.
+Vous ne pouvez pas l&apos;annuler.
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="DeleteItems">
@@ -2236,14 +2247,16 @@ Veuillez sélectionner un seul objet.
Votre carte de visite a été refusée.
</notification>
<notification name="TeleportToLandmark">
- Vous pouvez vous téléporter vers des endroits comme [NAME] en ouvrant le panneau Lieux sur le côté droit de votre écran, puis en sélectionnant l&apos;onglet Repères.
-Cliquez sur le repère de votre choix pour le sélectionner, puis sur Téléporter en bas du panneau.
-(Vous pouvez aussi double-cliquer sur le repère ou cliquer dessus avec le bouton droit de la souris et sélectionner Téléporter.)
+ Pour vous téléporter vers un lieu tel que [NAME], cliquez sur le bouton Endroits,
+ puis sélectionnez l&apos;onglet Repères dans la fenêtre qui s&apos;ouvre. Cliquez sur n&apos;importe quel
+ repère pour le sélectionner, puis sur Téléportation en bas de la fenêtre.
+ (Vous pouvez aussi double-cliquer sur le repère ou cliquer-droit dessus et
+ choisir Téléportation).
</notification>
<notification name="TeleportToPerson">
- Vous pouvez contacter des résidents comme [NAME] en ouvrant le panneau Résidents sur le côté droit de votre écran.
-Sélectionnez le résident de votre choix dans la liste, puis cliquez sur IM en bas du panneau.
-(Vous pouvez aussi double-cliquer sur le nom du résident dans la liste ou cliquer dessus avec le bouton droit de la souris et sélectionner IM.)
+ Pour contacter un résident tel que [NAME], cliquez sur le bouton Personnes, sélectionnez le résident dans la fenêtre qui s&apos;ouvre, puis cliquez sur IM en
+ bas de la fenêtre.
+ (Vous pouvez aussi double-cliquer sur le nom du résident dans la liste ou cliquer-droit dessus et choisir IM.)
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Vous ne pouvez pas sélectionner de terrain en dehors des limites du serveur.
@@ -2264,6 +2277,9 @@ Veuillez sélectionner un terrain plus petit.
<notification name="PaymentSent">
[MESSAGE]
</notification>
+ <notification name="PaymentFailure">
+ [MESSAGE]
+ </notification>
<notification name="EventNotification">
Avis d&apos;événement :
@@ -2798,7 +2814,7 @@ Voir le fichier journal pour plus de détails.
avec les résidents suivants :
[RESIDENTS] ?
- <usetemplate name="okcancelbuttons" notext="Annuler" yestext="Ok"/>
+ <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="ItemsShared">
Articles partagés.
@@ -2888,7 +2904,7 @@ Les résidents rejoignant l&apos;appel ultérieurement seront également
ignorés, même si vous quittez l&apos;appel.
Ignorer les autres ?
- <usetemplate ignoretext="Confirmer avant d&apos;ignorer les autres lors d&apos;un appel de groupe" name="okcancelignore" notext="Annuler" yestext="Ok"/>
+ <usetemplate ignoretext="Confirmer avant d&apos;ignorer les autres lors d&apos;un appel de groupe" name="okcancelignore" notext="Annuler" yestext="OK"/>
</notification>
<notification label="Chat" name="HintChat">
Pour participer à la conversation, saisissez du texte dans le champ de chat situé en dessous.
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_skin.xml b/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
index 9640adcdf8..f5f2738319 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skin_panel">
<panel name="avatar_skin_color_panel">
- <texture_picker label="Tatouage tête" name="Head Tattoos" tool_tip="Cliquez pour sélectionner une image" width="76"/>
- <texture_picker label="Tatouage haut" name="Upper Tattoos" tool_tip="Cliquez pour sélectionner une image" width="80"/>
- <texture_picker label="Tatouage bas" name="Lower Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
+ <texture_picker label="Tête" name="Head" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Haut du corps" name="Upper Body" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Bas du corps" name="Lower Body" tool_tip="Cliquer pour sélectionner une image."/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/fr/panel_nearby_chat.xml b/indra/newview/skins/default/xui/fr/panel_nearby_chat.xml
index 31cb3308e3..00bd6e81ae 100644
--- a/indra/newview/skins/default/xui/fr/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_nearby_chat.xml
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="nearby_chat">
- <check_box label="Traduction du chat" name="translate_chat_checkbox"/>
+ <check_box label="Traduire le chat" name="translate_chat_checkbox"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_postcard_message.xml b/indra/newview/skins/default/xui/fr/panel_postcard_message.xml
new file mode 100644
index 0000000000..0f8397cfb4
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_postcard_message.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_message">
+ <text name="to_label">
+ À :
+ </text>
+ <text name="name_label">
+ De :
+ </text>
+ <text name="subject_label">
+ Objet :
+ </text>
+ <line_editor label="Saisir ici votre objet" name="subject_form"/>
+ <text name="msg_label">
+ Message :
+ </text>
+ <text_editor name="msg_form">
+ Saisir ici votre message
+ </text_editor>
+ <button label="Annuler" name="cancel_btn"/>
+ <button label="Envoyer" name="send_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml b/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml
new file mode 100644
index 0000000000..6f4e9c23f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_settings">
+ <combo_box label="Résolution" name="postcard_size_combo">
+ <combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1 024 x 768" name="1024x768"/>
+ <combo_box.item label="Personnalisée" name="Custom"/>
+ </combo_box>
+ <layout_stack name="postcard_image_params_ls">
+ <layout_panel name="postcard_image_size_lp">
+ <spinner label="Largeur" name="postcard_snapshot_width"/>
+ <spinner label="Hauteur" name="postcard_snapshot_height"/>
+ <check_box label="Conserver les proportions" name="postcard_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="postcard_image_format_quality_lp">
+ <slider label="Qualité de l&apos;image" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index fa026d8106..76ed237451 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -29,30 +29,5 @@
<check_box label="Chats IM" name="EnableIMChatPopups" tool_tip="Cocher cette case pour qu&apos;un popup s&apos;affiche à réception d&apos;un message instantané."/>
<spinner label="Durée de vie du popup Chat près de moi :" name="nearby_toasts_lifetime"/>
<spinner label="Disparition progressive du popup Chat près de moi :" name="nearby_toasts_fadingtime"/>
- <check_box name="translate_chat_checkbox"/>
- <text name="translate_chb_label">
- Utiliser la traduction automatique lors des chats
- </text>
- <text name="translate_language_text">
- Traduire le chat en :
- </text>
- <combo_box name="translate_language_combobox">
- <combo_box.item label="Choix par défaut" name="System Default Language"/>
- <combo_box.item label="English (Anglais)" name="English"/>
- <combo_box.item label="Dansk (Danois)" name="Danish"/>
- <combo_box.item label="Deutsch (Allemand)" name="German"/>
- <combo_box.item label="Español (Espagnol)" name="Spanish"/>
- <combo_box.item label="Français" name="French"/>
- <combo_box.item label="Italiano (Italien)" name="Italian"/>
- <combo_box.item label="Magyar (Hongrois)" name="Hungarian"/>
- <combo_box.item label="Nederlands (Néerlandais)" name="Dutch"/>
- <combo_box.item label="Polski (Polonais)" name="Polish"/>
- <combo_box.item label="Português (Portugais)" name="Portugese"/>
- <combo_box.item label="Русский (Russe)" name="Russian"/>
- <combo_box.item label="Türkçe (Turc)" name="Turkish"/>
- <combo_box.item label="Українська (Ukrainien)" name="Ukrainian"/>
- <combo_box.item label="中文 (正體) (Chinois)" name="Chinese"/>
- <combo_box.item label="日本語 (Japonais)" name="Japanese"/>
- <combo_box.item label="한국어 (Coréen)" name="Korean"/>
- </combo_box>
+ <button label="Traduction automatique" name="ok_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml b/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml
index 82780c27c5..83303950dc 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml
@@ -15,7 +15,7 @@
Web :
</text>
<radio_group name="use_external_browser">
- <radio_item label="Utiliser mon navigateur (IE, Firefox, Safari)" name="external" tool_tip="Utiliser le navigateur web système par défaut pour l&apos;aide, les liens etc. Non recommandé en mode plein écran." value="1"/>
+ <radio_item label="Utiliser mon navigateur (IE, Firefox, Safari)" name="external" tool_tip="Utiliser le navigateur web système par défaut pour l&apos;aide, les liens etc. Non recommandé en mode plein écran." value="true"/>
<radio_item label="Utiliser le navigateur intégré" name="internal" tool_tip="Utilisez le navigateur intégré pour obtenir de l&apos;aide, ouvrir des liens, etc. Ce navigateur s&apos;ouvre dans [APP_NAME]." value=""/>
</radio_group>
<check_box initial_value="true" label="Activer les plugins" name="browser_plugins_enabled"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml
new file mode 100644
index 0000000000..4454d2475e
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_inventory">
+ <text name="title">
+ Enregistrer dans mon inventaire
+ </text>
+ <text name="hint_lbl">
+ L&apos;enregistrement d&apos;une image dans votre inventaire coûte [UPLOAD_COST] L$. Pour enregistrer votre image sous forme de texture, sélectionnez l&apos;un des formats carrés.
+ </text>
+ <combo_box label="Résolution" name="texture_size_combo">
+ <combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
+ <combo_box.item label="Petite (128 x 128)" name="Small(128x128)"/>
+ <combo_box.item label="Moyenne (256 x 256)" name="Medium(256x256)"/>
+ <combo_box.item label="Grande (512 x 512)" name="Large(512x512)"/>
+ <combo_box.item label="Personnalisée" name="Custom"/>
+ </combo_box>
+ <spinner label="Largeur" name="inventory_snapshot_width"/>
+ <spinner label="Hauteur" name="inventory_snapshot_height"/>
+ <check_box label="Conserver les proportions" name="inventory_keep_aspect_check"/>
+ <button label="Annuler" name="cancel_btn"/>
+ <button label="Enregistrer" name="save_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml
new file mode 100644
index 0000000000..41264521fd
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_local">
+ <text name="title">
+ Enregistrer sur mon ordinateur
+ </text>
+ <combo_box label="Résolution" name="local_size_combo">
+ <combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
+ <combo_box.item label="320 x 240" name="320x240"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1 024 x 768" name="1024x768"/>
+ <combo_box.item label="1 280 x 1 024" name="1280x1024"/>
+ <combo_box.item label="1 600 x 1 200" name="1600x1200"/>
+ <combo_box.item label="Personnalisée" name="Custom"/>
+ </combo_box>
+ <layout_stack name="local_image_params_ls">
+ <layout_panel name="local_image_size_lp">
+ <spinner label="Largeur" name="local_snapshot_width"/>
+ <spinner label="Hauteur" name="local_snapshot_height"/>
+ <check_box label="Conserver les proportions" name="local_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="local_image_format_quality_lp">
+ <combo_box label="Format" name="local_format_combo">
+ <combo_box.item label="PNG (sans perte)" name="PNG"/>
+ <combo_box.item label="JPEG" name="JPEG"/>
+ <combo_box.item label="BMP (sans perte)" name="BMP"/>
+ </combo_box>
+ <slider label="Qualité de l&apos;image" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <button label="Annuler" name="cancel_btn"/>
+ <flyout_button label="Enregistrer" name="save_btn" tool_tip="Enregistrer l&apos;image dans un fichier.">
+ <flyout_button.item label="Enregistrer" name="save_item"/>
+ <flyout_button.item label="Enregistrer sous..." name="saveas_item"/>
+ </flyout_button>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml
new file mode 100644
index 0000000000..db3fcbeac9
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_options">
+ <button label="Publier sur le flux de mon profil" name="save_to_profile_btn"/>
+ <button label="Envoyer par e-mail" name="save_to_email_btn"/>
+ <button label="Enregistrer dans mon inventaire ([AMOUNT] L$)" name="save_to_inventory_btn"/>
+ <button label="Enregistrer sur mon ordinateur" name="save_to_computer_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml
new file mode 100644
index 0000000000..bb23b52850
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_postcard">
+ <string name="default_subject">
+ Carte postale de [SECOND_LIFE].
+ </string>
+ <string name="default_message">
+ Ouvrez-moi !
+ </string>
+ <string name="upload_message">
+ Envoi en cours...
+ </string>
+ <text name="title">
+ Envoyer par e-mail
+ </text>
+ <button label="Message" name="message_btn"/>
+ <button label="Paramètres" name="settings_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_profile.xml
new file mode 100644
index 0000000000..427ffe2113
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_snapshot_profile.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_profile">
+ <text name="title">
+ Publier sur le flux de mon profil
+ </text>
+ <combo_box label="Résolution" name="profile_size_combo">
+ <combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1 024 x 768" name="1024x768"/>
+ <combo_box.item label="Personnalisée" name="Custom"/>
+ </combo_box>
+ <layout_stack name="profile_image_params_ls">
+ <layout_panel name="profile_image_size_lp">
+ <spinner label="Largeur" name="profile_snapshot_width"/>
+ <spinner label="Hauteur" name="profile_snapshot_height"/>
+ <check_box label="Conserver les proportions" name="profile_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="profile_image_metadata_lp">
+ <text name="caption_label">
+ Légende :
+ </text>
+ <check_box initial_value="true" label="Inclure l&apos;endroit" name="add_location_cb"/>
+ </layout_panel>
+ </layout_stack>
+ <button label="Annuler" name="cancel_btn"/>
+ <button label="Publier" name="post_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_status_bar.xml b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
index ac61eb7e52..c0d59a3182 100644
--- a/indra/newview/skins/default/xui/fr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
@@ -18,7 +18,7 @@
<panel name="balance_bg">
<text name="balance" tool_tip="Cliquer sur ce bouton pour actualiser votre solde en L$." value="20 L$"/>
<button label="Acheter L$" name="buyL" tool_tip="Cliquer pour acheter plus de L$."/>
- <button label="Achats" name="goShop" tool_tip="Ouvrir la Place du marché Second Life."/>
+ <button label="Achats" name="goShop" tool_tip="Ouvrir la Place du marché Second Life." width="75"/>
</panel>
<text name="TimeText" tool_tip="Heure actuelle (Pacifique)">
00h00 PST
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index f9f3366f63..d959a96565 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -1214,7 +1214,7 @@ Veuillez réessayer de vous connecter dans une minute.
Vous n&apos;avez pas de copie de cette texture dans votre inventaire
</string>
<string name="InventoryInboxNoItems">
- Ici seront livrés les articles achetés sur la Place du marché.
+ Lorsque vous achetez ou recevez un article, il s&apos;affiche ici. Vous pouvez alors le faire glisser vers un dossier de votre inventaire ou le supprimer si vous ne souhaitez pas le conserver.
</string>
<string name="MarketplaceURL">
http://marketplace.[DOMAIN_NAME]
@@ -1412,6 +1412,9 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="no_attachments">
Aucun élément attaché porté
</string>
+ <string name="Attachments remain">
+ Éléments attachés ([COUNT] emplacements restants)
+ </string>
<string name="Buy">
Acheter
</string>
@@ -1538,6 +1541,12 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="Right Pec">
Pectoral droit
</string>
+ <string name="Neck">
+ Cou
+ </string>
+ <string name="Avatar Center">
+ Centre de l&apos;avatar
+ </string>
<string name="Invalid Attachment">
Point d&apos;attache non valide
</string>
@@ -4030,6 +4039,18 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
<string name="you_paid_ldollars_no_name">
Vous avez payé à [AMOUNT] L$ [REASON].
</string>
+ <string name="you_paid_failure_ldollars">
+ Votre paiement de [AMOUNT] L$ à [NAME] [REASON] a échoué.
+ </string>
+ <string name="you_paid_failure_ldollars_no_info">
+ Votre paiement de [AMOUNT] L$ a échoué.
+ </string>
+ <string name="you_paid_failure_ldollars_no_reason">
+ Votre paiement de [AMOUNT] L$ à [NAME] a échoué.
+ </string>
+ <string name="you_paid_failure_ldollars_no_name">
+ Votre paiement de [AMOUNT] L$ [REASON] a échoué.
+ </string>
<string name="for item">
pour l&apos;article suivant : [ITEM]
</string>
@@ -4440,6 +4461,12 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="ExternalEditorFailedToRun">
Échec d&apos;exécution de l&apos;éditeur externe.
</string>
+ <string name="TranslationFailed">
+ Échec de traduction : [REASON]
+ </string>
+ <string name="TranslationResponseParseError">
+ Erreur lors de l&apos;analyse de la réponse relative à la traduction.
+ </string>
<string name="Esc">
Échap
</string>
@@ -4810,7 +4837,7 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
Mini-carte
</string>
<string name="Command_Move_Label">
- Bouger
+ Marcher / Courir / Voler
</string>
<string name="Command_People_Label">
Personnes
@@ -4837,10 +4864,10 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
Parler
</string>
<string name="Command_View_Label">
- Affichage
+ Paramètres de la caméra
</string>
<string name="Command_Voice_Label">
- Chat près de vous
+ Paramètres vocaux
</string>
<string name="Command_AboutLand_Tooltip">
Information sur le terrain que vous visitez
@@ -4912,7 +4939,16 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
Changer l&apos;angle de la caméra
</string>
<string name="Command_Voice_Tooltip">
- Personnes près de vous avec le chat vocal
+ Commandes de réglage du volume des appels et des personnes près de vous dans Second Life.
+ </string>
+ <string name="Toolbar_Bottom_Tooltip">
+ actuellement dans la barre d&apos;outils du bas
+ </string>
+ <string name="Toolbar_Left_Tooltip">
+ actuellement dans la barre d&apos;outils de gauche
+ </string>
+ <string name="Toolbar_Right_Tooltip">
+ actuellement dans la barre d&apos;outils de droite
</string>
<string name="Retain%">
Garder%
@@ -4938,4 +4974,19 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="Normal">
Normal
</string>
+ <string name="snapshot_quality_very_low">
+ Très faible
+ </string>
+ <string name="snapshot_quality_low">
+ Faible
+ </string>
+ <string name="snapshot_quality_medium">
+ Moyenne
+ </string>
+ <string name="snapshot_quality_high">
+ Élevée
+ </string>
+ <string name="snapshot_quality_very_high">
+ Très élevée
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/fr/teleport_strings.xml b/indra/newview/skins/default/xui/fr/teleport_strings.xml
index 401b272c81..d0c74ff353 100644
--- a/indra/newview/skins/default/xui/fr/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/fr/teleport_strings.xml
@@ -21,8 +21,8 @@ Si vous ne parvenez toujours pas à être téléporté, déconnectez-vous puis r
Veuillez réessayer dans un moment.
</message>
<message name="NoHelpIslandTP">
- Vous ne pouvez pas retourner sur Welcome Island.
-Pour répéter le didacticiel, veuillez aller sur Welcome Island Public.
+ Vous ne pouvez pas vous téléporter à nouveau vers Welcome Island.
+Pour recommencer le didacticiel, accédez à Welcome Island Public.
</message>
<message name="noaccess_tport">
Désolé, vous n&apos;avez pas accès à cette destination.
diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml
index 68d073a766..39114b7bf7 100644
--- a/indra/newview/skins/default/xui/it/floater_about.xml
+++ b/indra/newview/skins/default/xui/it/floater_about.xml
@@ -67,32 +67,34 @@ Versione Server voice: [VOICE_VERSION]
<panel label="Licenze" name="licenses_panel">
<text_editor name="credits_editor">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
-APR Copyright (C) 2000-2004 The Apache Software Foundation
-Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
-cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
-DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
-expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
-FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
-GL Copyright (C) 1999-2004 Brian Paul.
-GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
-google-perftools Copyright (c) 2005, Google Inc.
-Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
-jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
-jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
-ogg/vorbis Copyright (C) 2001, Xiphophorus
-OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
-PCRE Copyright (c) 1997-2008 University of Cambridge
-SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
-SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
-zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
-google-perftools Copyright (c) 2005, Google Inc.
+ APR Copyright (C) 2000-2004 The Apache Software Foundation
+ Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
+ expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+ FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ GL Copyright (C) 1999-2004 Brian Paul.
+ GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
+ google-perftools Copyright (c) 2005, Google Inc.
+ Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
+ jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
+ jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
+ ogg/vorbis Copyright (C) 2001, Xiphophorus
+ OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2008 University of Cambridge
+ SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+ SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
+ zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
+ google-perftools Copyright (c) 2005, Google Inc.
-Il Viewer Second Life utilizza Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e licenziatari). Tutti i diritti riservati. Per informazioni dettagliate, vedere www.havok.com.
+ Il Viewer Second Life utilizza Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e licenziatari). Tutti i diritti riservati. Per informazioni dettagliate, vedere www.havok.com.
-Tutti i diritti riservati. Per informazioni dettagliate, vedere licenses.txt.
+ Questo software contiene codice sorgente fornito da NVIDIA Corporation.
-Codifica audio chat vocale: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
+ Tutti i diritti riservati. Per informazioni dettagliate, vedere licenses.txt.
+
+ Codifica audio chat vocale: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
</text_editor>
</panel>
</tab_container>
diff --git a/indra/newview/skins/default/xui/it/floater_about_land.xml b/indra/newview/skins/default/xui/it/floater_about_land.xml
index b6bfb4aadf..528cf185fc 100644
--- a/indra/newview/skins/default/xui/it/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/it/floater_about_land.xml
@@ -133,7 +133,7 @@ Vai al menu Mondo &gt; Informazioni sul terreno oppure seleziona un altro appezz
Traffico:
</text>
<text name="DwellText" width="140">
- 0
+ Caricamento in corso...
</text>
<button label="Acquista il terreno..." label_selected="Acquista il terreno..." left="130" name="Buy Land..." width="125"/>
<button label="Vendita Linden" name="Linden Sale..." tool_tip="La terra deve essere di proprietà, con contenuto impostato, e non già messa all&apos;asta."/>
@@ -314,13 +314,15 @@ Solamente terreni più grandi possono essere abilitati nella ricerca.
Nessuna spinta (Impostazione regionale)
</panel.string>
<panel.string name="see_avs_text">
- Vedi i residenti in questo lotto e chatta con loro
+ Gli avatar in altri lotti possono vedere
</panel.string>
<text name="allow_label">
Permetti ad altri residenti di:
</text>
- <check_box label="Modificare il terreno" name="edit land check" tool_tip="Se spuntata, chiunque può terraformare il tuo terreno. È preferibile lasciare questa opzione non spuntata, dato che sarai comunque in grado di modificare il tuo terreno."/>
- <check_box label="Permetti il volo" name="check fly" tool_tip="Se spuntato, gli altri residenti potranno volare sul tuo terreno. Se non spuntato, potranno solamente arrivare in volo o sorvolare il terreno."/>
+ <text name="allow_label0">
+ Vola:
+ </text>
+ <check_box label="Tutti" name="check fly" tool_tip="Se spuntato, gli altri residenti potranno volare sul tuo terreno. Se non spuntato, potranno solamente arrivare in volo o sorvolare il terreno."/>
<text name="allow_label2">
Creare oggetti:
</text>
@@ -336,9 +338,6 @@ Solamente terreni più grandi possono essere abilitati nella ricerca.
</text>
<check_box label="Tutti i residenti" name="check other scripts"/>
<check_box label="Gruppo" name="check group scripts"/>
- <text name="land_options_label">
- Opzioni per il terreno:
- </text>
<check_box label="Sicuro (senza danno)" name="check safe" tool_tip="Se spuntato, imposta il terreno su &apos;sicuro&apos;, disabilitando i danni da combattimento. Se non spuntato, viene abilitato il combattimento con danni."/>
<check_box label="Nessuna spinta" name="PushRestrictCheck" tool_tip="Previeni i colpi. Selezionare questa opzione può essere utile per prevenire comportamenti dannosi sul tuo terreno."/>
<check_box label="Mostra luogo nella ricerca (30 L$/settimana)" name="ShowDirectoryCheck" tool_tip="Consenti che il lotto sia visto nei risultati di ricerca"/>
@@ -379,9 +378,9 @@ Solamente terreni più grandi possono essere abilitati nella ricerca.
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Clicca per scegliere una immagine"/>
<text name="allow_label5">
- Permetti ai residenti in altri lotti di:
+ e chattare con avatar in questo lotto
</text>
- <check_box label="Vedi avatar" name="SeeAvatarsCheck" tool_tip="Consente ai residenti in altri lotti di vedere i residenti in questo lotto e chattare con loro, e ti consente di vederli e chattare con loro."/>
+ <check_box label="Vedi avatar" name="SeeAvatarsCheck" tool_tip="Consente ad avatar in altri lotti di vedere e chattare con avatar in questo lotto e viceversa."/>
<text name="landing_point">
Punto di atterraggio: [LANDING]
</text>
diff --git a/indra/newview/skins/default/xui/it/floater_avatar.xml b/indra/newview/skins/default/xui/it/floater_avatar.xml
index 1587c347a5..d7445cfb2b 100644
--- a/indra/newview/skins/default/xui/it/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/it/floater_avatar.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Avatar" title="SCELTA AVATAR"/>
+<floater name="Avatar" title="SELEZIONA UN AVATAR"/>
diff --git a/indra/newview/skins/default/xui/it/floater_buy_currency.xml b/indra/newview/skins/default/xui/it/floater_buy_currency.xml
index d985ad2b3c..743969f557 100644
--- a/indra/newview/skins/default/xui/it/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/it/floater_buy_currency.xml
@@ -46,7 +46,7 @@
[AMT]L$
</text>
<text name="currency_links">
- [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
+ [http://www.secondlife.com/my/account/payment_method_management.php metodo di pagamento] | [http://www.secondlife.com/my/account/currency.php valuta]
</text>
<text name="exchange_rate_note">
Riscrivi l&apos;importo per vedere l&apos;ultimo tasso al cambio.
diff --git a/indra/newview/skins/default/xui/it/floater_camera.xml b/indra/newview/skins/default/xui/it/floater_camera.xml
index 7e6ca4307e..be03857bc9 100644
--- a/indra/newview/skins/default/xui/it/floater_camera.xml
+++ b/indra/newview/skins/default/xui/it/floater_camera.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="camera_floater" title="VISTA">
+<floater name="camera_floater" title="CONTROLLI FOTOCAMERA">
<floater.string name="rotate_tooltip">
Ruota la telecamera Intorno all&apos;Inquadratura
</floater.string>
diff --git a/indra/newview/skins/default/xui/it/floater_chat_bar.xml b/indra/newview/skins/default/xui/it/floater_chat_bar.xml
index 6c5c8fbea0..94c85b50c8 100644
--- a/indra/newview/skins/default/xui/it/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/it/floater_chat_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="chat_bar" title="CHAT NEI DINTORNI">
- <panel>
+ <panel name="bottom_panel">
<line_editor label="Clicca qui per la chat." name="chat_box" tool_tip="Premi Invio per parlare, Ctrl+Invio per gridare"/>
<button name="show_nearby_chat" tool_tip="Mostra/Nasconde il registro della chat nei dintorni"/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/floater_hardware_settings.xml b/indra/newview/skins/default/xui/it/floater_hardware_settings.xml
index 561f8dbf34..5d3ae04a4d 100644
--- a/indra/newview/skins/default/xui/it/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/it/floater_hardware_settings.xml
@@ -4,7 +4,7 @@
Filtraggio:
</text>
<check_box label="Filtraggio Anisotropico (rallenta se attivato)" name="ani"/>
- <text name="Antialiasing:">
+ <text name="antialiasing label">
Antialiasing:
</text>
<combo_box label="Antialiasing" name="fsaa" width="94">
diff --git a/indra/newview/skins/default/xui/it/floater_model_preview.xml b/indra/newview/skins/default/xui/it/floater_model_preview.xml
index 03102f5f81..ca36fd2def 100644
--- a/indra/newview/skins/default/xui/it/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/it/floater_model_preview.xml
@@ -4,6 +4,9 @@
<string name="status_parse_error">
Errore: Errore elaborazione Dae - vedere il registro per informazioni dettagliate.
</string>
+ <string name="status_material_mismatch">
+ Errore: il materiale del modello non è un sottoinsieme del modello di riferimento.
+ </string>
<string name="status_reading_file">
Caricamento in corso...
</string>
diff --git a/indra/newview/skins/default/xui/it/floater_model_wizard.xml b/indra/newview/skins/default/xui/it/floater_model_wizard.xml
index e6d0a7c4bc..7c1b13c18f 100644
--- a/indra/newview/skins/default/xui/it/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/it/floater_model_wizard.xml
@@ -20,6 +20,9 @@
Scegli il file del modello da caricare
</text>
<button label="Sfoglia..." label_selected="Sfoglia..." name="browse"/>
+ <text name="Model types">
+ Second Life supporta file COLLADA (.dae)
+ </text>
<text name="dimensions">
X Y Z
</text>
diff --git a/indra/newview/skins/default/xui/it/floater_moveview.xml b/indra/newview/skins/default/xui/it/floater_moveview.xml
index 6e820a335c..1237bd06a9 100644
--- a/indra/newview/skins/default/xui/it/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/it/floater_moveview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="move_floater" title="SPOSTA">
+<floater name="move_floater" title="CAMMINA / CORRI / VOLA">
<string name="walk_forward_tooltip">
Cammina in avanti (premi freccia su o W)
</string>
diff --git a/indra/newview/skins/default/xui/it/floater_snapshot.xml b/indra/newview/skins/default/xui/it/floater_snapshot.xml
index f1c5cc4caf..bff6081bdf 100644
--- a/indra/newview/skins/default/xui/it/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/it/floater_snapshot.xml
@@ -3,73 +3,63 @@
<floater.string name="unknown">
sconosciuto
</floater.string>
- <radio_group label="Tipo di fotografia" name="snapshot_type_radio">
- <radio_item label="E-mail" name="postcard"/>
- <radio_item label="Il mio inventario (L$[AMOUNT])" name="texture"/>
- <radio_item label="Salva sul mio computer" name="local"/>
- </radio_group>
+ <string name="postcard_progress_str">
+ Invio e-mail in corso
+ </string>
+ <string name="profile_progress_str">
+ Caricamento post
+ </string>
+ <string name="inventory_progress_str">
+ Salva nell&apos;inventario
+ </string>
+ <string name="local_progress_str">
+ Salvataggio sul computer in corso
+ </string>
+ <string name="profile_succeeded_str">
+ Immagine caricata
+ </string>
+ <string name="postcard_succeeded_str">
+ E-mail inviata.
+ </string>
+ <string name="inventory_succeeded_str">
+ Salvato nell&apos;inventario.
+ </string>
+ <string name="local_succeeded_str">
+ Salvato sul computer.
+ </string>
+ <string name="profile_failed_str">
+ Caricamento immagine sul feed del profilo non riuscito.
+ </string>
+ <string name="postcard_failed_str">
+ Invio e-mail non riuscito.
+ </string>
+ <string name="inventory_failed_str">
+ Non salvato nell&apos;inventario.
+ </string>
+ <string name="local_failed_str">
+ Non salvato sul computer.
+ </string>
+ <button name="advanced_options_btn" tool_tip="Opzioni Avanzate"/>
+ <text name="image_res_text">
+ [WIDTH] x [HEIGHT] px
+ </text>
<text name="file_size_label">
[SIZE] KB
</text>
- <button label="Aggiorna la fotografia" name="new_snapshot_btn"/>
- <button label="Invia" name="send_btn"/>
- <button label="Salva ([AMOUNT] L$)" name="upload_btn"/>
- <flyout_button label="Salva" name="save_btn" tool_tip="Salva immagine come file">
- <flyout_button.item label="Salva" name="save_item"/>
- <flyout_button.item label="Salva con nome..." name="saveas_item"/>
- </flyout_button>
- <button label="Altro" name="more_btn" tool_tip="Opzioni Avanzate"/>
- <button label="Meno" name="less_btn" tool_tip="Opzioni Avanzate"/>
- <button label="Annulla" name="discard_btn"/>
- <text name="type_label2">
- Dimensioni
- </text>
- <text name="format_label">
- Formato
- </text>
- <combo_box label="Risoluzione" name="postcard_size_combo">
- <combo_box.item label="Finestra attuale" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="Personalizza" name="Custom"/>
- </combo_box>
- <combo_box label="Risoluzione" name="texture_size_combo">
- <combo_box.item label="Finestra attuale" name="CurrentWindow"/>
- <combo_box.item label="Piccola (128x128)" name="Small(128x128)"/>
- <combo_box.item label="Media (256x256)" name="Medium(256x256)"/>
- <combo_box.item label="Grande (512x512)" name="Large(512x512)"/>
- <combo_box.item label="Personalizza" name="Custom"/>
- </combo_box>
- <combo_box label="Risoluzione" name="local_size_combo">
- <combo_box.item label="Finestra attuale" name="CurrentWindow"/>
- <combo_box.item label="320x240" name="320x240"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1280x1024" name="1280x1024"/>
- <combo_box.item label="1600x1200" name="1600x1200"/>
- <combo_box.item label="Personalizza" name="Custom"/>
- </combo_box>
- <combo_box label="Formato" name="local_format_combo">
- <combo_box.item label="PNG" name="PNG"/>
- <combo_box.item label="JPEG" name="JPEG"/>
- <combo_box.item label="BMP" name="BMP"/>
- </combo_box>
- <spinner label="Larghezza" name="snapshot_width"/>
- <spinner label="Altezza" name="snapshot_height"/>
- <check_box label="Mantieni le proporzioni" name="keep_aspect_check"/>
- <slider label="Qualità dell&apos;immagine" name="image_quality_slider"/>
- <text name="layer_type_label">
- Cattura:
- </text>
- <combo_box label="Layer dell&apos;immagine" name="layer_types">
- <combo_box.item label="Colori" name="Colors"/>
- <combo_box.item label="Profondità" name="Depth"/>
- </combo_box>
- <check_box label="Interfaccia" name="ui_check"/>
- <check_box label="HUD" name="hud_check"/>
- <check_box label="Tieni aperta dopo il salvataggio" name="keep_open_check"/>
- <check_box label="Congela il frame (tutto schermo)" name="freeze_frame_check"/>
- <check_box label="Aggiornamento automatico" name="auto_snapshot_check"/>
+ <panel name="advanced_options_panel">
+ <text name="advanced_options_label">
+ OPZIONI AVANZATE
+ </text>
+ <text name="layer_type_label">
+ Cattura:
+ </text>
+ <combo_box label="Layer dell&apos;immagine" name="layer_types">
+ <combo_box.item label="Colori" name="Colors"/>
+ <combo_box.item label="Profondità" name="Depth"/>
+ </combo_box>
+ <check_box label="Interfaccia" name="ui_check"/>
+ <check_box label="HUD" name="hud_check"/>
+ <check_box label="Congela il frame (tutto schermo)" name="freeze_frame_check"/>
+ <check_box label="Aggiornamento automatico" name="auto_snapshot_check"/>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_toybox.xml b/indra/newview/skins/default/xui/it/floater_toybox.xml
index c8d5f1ed7c..269e2831d0 100644
--- a/indra/newview/skins/default/xui/it/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/it/floater_toybox.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Toybox" title="PERSONALIZZA BARRE STRUMENTI">
+<floater name="Toybox" title="PULSANTI BARRA STRUMENTI">
<text name="toybox label 1">
Aggiungere o rimuovere pulsanti trascinandoli dentro o fuori dalle barre strumenti.
</text>
<text name="toybox label 2">
I pulsanti verranno visualizzati come mostrato o solo come icone, a seconda delle impostazioni della singola barra degli strumenti.
</text>
+ <button label="Cancella tutte le barre strumenti" label_selected="Cancella tutte le barre strumenti" name="btn_clear_all"/>
<button label="Ripristina predefiniti" label_selected="Ripristina predefiniti" name="btn_restore_defaults"/>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_translation_settings.xml b/indra/newview/skins/default/xui/it/floater_translation_settings.xml
new file mode 100644
index 0000000000..a0a34da723
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_translation_settings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_translation_settings" title="IMPOSTAZIONI TRADUZIONE CHAT">
+ <string name="bing_api_key_not_verified">
+ appID Bing non verificato. Riprova.
+ </string>
+ <string name="google_api_key_not_verified">
+ Chiave API Google non verificata. Riprova.
+ </string>
+ <string name="bing_api_key_verified">
+ appID Bing verificato.
+ </string>
+ <string name="google_api_key_verified">
+ Chiave API Google verificata.
+ </string>
+ <check_box label="Usa la traduzione meccanica durante le chat" name="translate_chat_checkbox"/>
+ <text name="translate_language_label">
+ Traduci chat in:
+ </text>
+ <combo_box name="translate_language_combo">
+ <combo_box.item label="Predefinito di sistema" name="System Default Language"/>
+ <combo_box.item label="English (Inglese)" name="English"/>
+ <combo_box.item label="Dansk (Danese)" name="Danish"/>
+ <combo_box.item label="Deutsch (Tedesco)" name="German"/>
+ <combo_box.item label="Español (Spagnolo)" name="Spanish"/>
+ <combo_box.item label="Français (Francese)" name="French"/>
+ <combo_box.item label="Italiano" name="Italian"/>
+ <combo_box.item label="Magyar (Ungherese)" name="Hungarian"/>
+ <combo_box.item label="Nederlands (Olandese)" name="Dutch"/>
+ <combo_box.item label="Polski (Polacco)" name="Polish"/>
+ <combo_box.item label="Português (Portoghese)" name="Portugese"/>
+ <combo_box.item label="Русский (Russo)" name="Russian"/>
+ <combo_box.item label="Türkçe (Turco)" name="Turkish"/>
+ <combo_box.item label="Українська (Ucraino)" name="Ukrainian"/>
+ <combo_box.item label="中文 (正體) (Cinese)" name="Chinese"/>
+ <combo_box.item label="日本語 (Giapponese)" name="Japanese"/>
+ <combo_box.item label="한국어 (Coreano)" name="Korean"/>
+ </combo_box>
+ <text name="tip">
+ Seleziona il servizio di traduzione:
+ </text>
+ <radio_group name="translation_service_rg">
+ <radio_item initial_value="bing" label="Bing Translator" name="bing"/>
+ <radio_item initial_value="google" label="Google Translate" name="google"/>
+ </radio_group>
+ <text name="bing_api_key_label">
+ Bing [http://www.bing.com/developers/createapp.aspx AppID]:
+ </text>
+ <button label="Verifica" name="verify_bing_api_key_btn"/>
+ <text name="google_api_key_label">
+ Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API key]:
+ </text>
+ <button label="Verifica" name="verify_google_api_key_btn"/>
+ <text name="google_links_text">
+ [http://code.google.com/apis/language/translate/v2/pricing.html Prezzi] | [https://code.google.com/apis/console Statistiche]
+ </text>
+ <button label="OK" name="ok_btn"/>
+ <button label="Annulla" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_voice_controls.xml b/indra/newview/skins/default/xui/it/floater_voice_controls.xml
index d0ac815b8b..77973eef1e 100644
--- a/indra/newview/skins/default/xui/it/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/it/floater_voice_controls.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_voice_controls" title="CONTROLLI VOCE">
<string name="title_nearby">
- Voce vicina
+ IMPOSTAZIONI VOCE
</string>
<string name="title_group">
- Chiamata di gruppo con [GROUP]
+ CHIAMATA DI GRUPPO CON [GROUP]
</string>
<string name="title_adhoc">
- Chiamata in conferenza
+ CHIAMATA IN CONFERENZA
</string>
<string name="title_peer_2_peer">
- Chiamata con [NAME]
+ CHIAMATA CON [NAME]
</string>
<string name="no_one_near">
Nessuno nei dintorni ha attivato la funzione voce
diff --git a/indra/newview/skins/default/xui/it/menu_toolbars.xml b/indra/newview/skins/default/xui/it/menu_toolbars.xml
index 784ecd262c..604ca763d1 100644
--- a/indra/newview/skins/default/xui/it/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/it/menu_toolbars.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Toolbars Popup">
- <menu_item_call label="Seleziona pulsanti..." name="Chose Buttons"/>
+ <menu_item_call label="Rimuovi questo pulsante" name="Remove button"/>
+ <menu_item_call label="Pulsanti barra strumenti..." name="Choose Buttons"/>
<menu_item_check label="Icone ed etichette" name="icons_with_text"/>
<menu_item_check label="Solo icone" name="icons_only"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml
index 8792a0fc19..5140d2b1ec 100644
--- a/indra/newview/skins/default/xui/it/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/it/menu_viewer.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu_bar name="Main Menu">
<menu label="Io" name="Me">
- <menu_item_call label="Dashboard..." name="Manage My Account">
- <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=it"/>
- </menu_item_call>
<menu_item_call label="Profilo..." name="Profile"/>
<menu_item_call label="Aspetto fisico..." name="ChangeOutfit"/>
+ <menu_item_call label="Scegli un avatar..." name="Avatar Picker"/>
<menu_item_check label="Inventario..." name="Inventory"/>
- <menu_item_check label="Gesture..." name="Gestures"/>
- <menu_item_check label="Voce..." name="ShowVoice"/>
+ <menu_item_call label="Nuova finestra inventario" name="NewInventoryWindow"/>
+ <menu_item_call label="Luoghi..." name="Places"/>
+ <menu_item_call label="Preferiti..." name="Picks"/>
+ <menu_item_call label="Controlli fotocamera..." name="Camera Controls"/>
<menu label="Spostamento" name="Movement">
<menu_item_call label="Siedi" name="Sit Down Here"/>
<menu_item_check label="Vola" name="Fly"/>
@@ -22,34 +22,39 @@
<menu_item_call label="Richiedi diritti Admin" name="Request Admin Options"/>
<menu_item_call label="Lascia stato Admin" name="Leave Admin Options"/>
<menu_item_call label="Compra L$" name="Buy and Sell L$"/>
+ <menu_item_call label="Dashboard dell&apos;account..." name="Manage My Account">
+ <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=it"/>
+ </menu_item_call>
<menu_item_call label="Preferenze..." name="Preferences"/>
- <menu_item_call label="Barre strumenti..." name="Toolbars"/>
+ <menu_item_call label="Pulsanti barra strumenti..." name="Toolbars"/>
<menu_item_call label="Nascondi tutti i controlli" name="Hide UI"/>
<menu_item_call label="Esci da [APP_NAME]" name="Quit"/>
</menu>
<menu label="Comunica" name="Communicate">
- <menu_item_call label="I miei amici..." name="My Friends"/>
- <menu_item_call label="I miei gruppi" name="My Groups"/>
- <menu_item_check label="Chat nei dintorni" name="Nearby Chat"/>
+ <menu_item_check label="Chat..." name="Nearby Chat"/>
+ <menu_item_check label="Parla" name="Speak"/>
+ <menu_item_check label="Impostazioni voce..." name="Nearby Voice"/>
+ <menu_item_check label="Manipolazione voce..." name="ShowVoice"/>
+ <menu_item_check label="Gesture..." name="Gestures"/>
+ <menu_item_call label="Amici" name="My Friends"/>
+ <menu_item_call label="Gruppi" name="My Groups"/>
<menu_item_call label="Persone vicine" name="Active Speakers"/>
- <menu_item_check label="Voce nei dintorni" name="Nearby Voice"/>
</menu>
<menu label="Mondo" name="World">
+ <menu_item_call label="Crea punto di riferimento per questo luogo" name="Create Landmark Here"/>
+ <menu_item_call label="Destinazioni..." name="Destinations"/>
+ <menu_item_check label="Mappamondo" name="World Map"/>
<menu_item_check label="Mini mappa" name="Mini-Map"/>
- <menu_item_check label="Mappa del mondo" name="World Map"/>
<menu_item_check label="Cerca" name="Search"/>
+ <menu_item_call label="Teleport a Casa" name="Teleport Home"/>
+ <menu_item_call label="Imposta come Casa mia" name="Set Home to Here"/>
<menu_item_call label="Istantanea" name="Take Snapshot"/>
- <menu_item_call label="Crea punto di riferimento per questo luogo" name="Create Landmark Here"/>
- <menu label="Profilo del luogo" name="Land">
- <menu_item_call label="Profilo del luogo" name="Place Profile"/>
- <menu_item_call label="Informazioni sui terreni" name="About Land"/>
- <menu_item_call label="Regione/proprietà immobiliare" name="Region/Estate"/>
- </menu>
+ <menu_item_call label="Profilo del luogo" name="Place Profile"/>
+ <menu_item_call label="Informazioni sul terreno" name="About Land"/>
+ <menu_item_call label="Regione/proprietà immobiliare" name="Region/Estate"/>
+ <menu_item_call label="Terreni posseduti..." name="My Land"/>
<menu_item_call label="Acquista questo terreno" name="Buy Land"/>
- <menu_item_call label="Il mio terreno" name="My Land"/>
<menu label="Mostra" name="LandShow">
- <menu_item_check label="Comandi del movimento" name="Movement Controls"/>
- <menu_item_check label="Comandi visualizzazione" name="Camera Controls"/>
<menu_item_check label="Linee di divieto" name="Ban Lines"/>
<menu_item_check label="Marcatori" name="beacons"/>
<menu_item_check label="Linee di confine" name="Property Lines"/>
@@ -58,29 +63,28 @@
<menu_item_check label="Proprietà del lotto" name="Parcel Properties"/>
<menu_item_check label="Menu Avanzato" name="Show Advanced Menu"/>
</menu>
- <menu_item_call label="Teleport a Casa" name="Teleport Home"/>
- <menu_item_call label="Imposta come Casa mia" name="Set Home to Here"/>
<menu label="Sole" name="Environment Settings">
<menu_item_call label="Alba" name="Sunrise"/>
<menu_item_call label="Mezzogiorno" name="Noon"/>
<menu_item_call label="Tramonto" name="Sunset"/>
<menu_item_call label="Mezzanotte" name="Midnight"/>
+ <menu_item_call label="Usa impostazioni regione" name="Use Region Settings"/>
</menu>
- <menu label="Editor ambiente" name="Enviroment Editor">
- <menu_item_call label="Impostazioni ambiente..." name="Enviroment Settings"/>
+ <menu label="Editor ambiente" name="Environment Editor">
+ <menu_item_call label="Impostazioni ambiente..." name="Environment Settings"/>
<menu label="Valori predefiniti acqua" name="Water Presets">
<menu_item_call label="Nuovo valore predefinito..." name="new_water_preset"/>
- <menu_item_call label="Modifica valori predefiniti..." name="edit_water_preset"/>
+ <menu_item_call label="Modifica valore predefinito..." name="edit_water_preset"/>
<menu_item_call label="Cancella valore predefinito..." name="delete_water_preset"/>
</menu>
<menu label="Valori predefiniti cielo" name="Sky Presets">
<menu_item_call label="Nuovo valore predefinito..." name="new_sky_preset"/>
- <menu_item_call label="Modifica valori predefiniti..." name="edit_sky_preset"/>
+ <menu_item_call label="Modifica valore predefinito..." name="edit_sky_preset"/>
<menu_item_call label="Cancella valore predefinito..." name="delete_sky_preset"/>
</menu>
- <menu label="Valori predefiniti giornata" name="Day Presets">
+ <menu label="Valori predefiniti giorno" name="Day Presets">
<menu_item_call label="Nuovo valore predefinito..." name="new_day_preset"/>
- <menu_item_call label="Modifica valori predefiniti..." name="edit_day_preset"/>
+ <menu_item_call label="Modifica valore predefinito..." name="edit_day_preset"/>
<menu_item_call label="Cancella valore predefinito..." name="delete_day_preset"/>
</menu>
</menu>
@@ -146,6 +150,7 @@
<menu_item_call label="Ripeti" name="Redo"/>
</menu>
<menu label="Aiuto" name="Help">
+ <menu_item_call label="Istruzioni..." name="How To"/>
<menu_item_call label="Aiuto di [SECOND_LIFE]" name="Second Life Help"/>
<menu_item_call label="Segnala abuso" name="Report Abuse"/>
<menu_item_call label="Segnala bug" name="Report Bug"/>
@@ -199,11 +204,10 @@
<menu_item_check label="Usa thread lettura plugin" name="Use Plugin Read Thread"/>
<menu_item_call label="Pulisci cache di gruppo" name="ClearGroupCache"/>
<menu_item_check label="Fluidità mouse" name="Mouse Smoothing"/>
+ <menu_item_call label="Rilascia tasti" name="Release Keys"/>
<menu label="Scorciatoie" name="Shortcuts">
<menu_item_call label="Immagine ([COST]L$)..." name="Upload Image"/>
<menu_item_check label="Cerca" name="Search"/>
- <menu_item_call label="Rilascia tasti" name="Release Keys"/>
- <menu_item_call label="Imposta dimensioni dell&apos;interfaccia sui valori predefiniti" name="Set UI Size to Default"/>
<menu_item_check label="Mostra menu Avanzato - tasti di scelta rapida esistenti" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="Chiudi finestra" name="Close Window"/>
<menu_item_call label="Chiudi tutte le finestre" name="Close All Windows"/>
@@ -272,6 +276,7 @@
<menu_item_check label="Aggiorna tipo" name="Update Type"/>
<menu_item_check label="Info livello dettaglio" name="LOD Info"/>
<menu_item_check label="Crea coda" name="Build Queue"/>
+ <menu_item_check label="Vettori vento" name="Wind Vectors"/>
<menu_item_check label="Complessità rendering" name="rendercomplexity"/>
<menu_item_check label="Scolpisci" name="Sculpt"/>
</menu>
@@ -281,7 +286,6 @@
<menu_item_check label="Luci e ombre" name="Lighting and Shadows"/>
<menu_item_check label="Ombra dal sole, dalla luna e dai proiettori" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO e ombre fluide" name="SSAO and Shadow Smoothing"/>
- <menu_item_check label="Illuminazione globale (sperimentale)" name="Global Illumination"/>
<menu_item_check label="Maschera alfa automatica (differita)" name="Automatic Alpha Masks (deferred)"/>
<menu_item_check label="Maschera alfa automatica (non differita)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Texture delle animazioni" name="Animation Textures"/>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 2db0892cd6..fcc515186d 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -1110,8 +1110,13 @@ Cedere questi [AREA] m² di terreno al gruppo &apos;[GROUP_NAME]&apos;?
<notification name="DisplaySetToSafe">
Le impostazioni dello schermo sono state impostate a valori di sicurezza perchè hai specificato l&apos;opzione -safe.
</notification>
- <notification name="DisplaySetToRecommended">
- Le impostazioni dello schermo sono state impostate a valori ottimali basati sulla tua configurazione di sistema.
+ <notification name="DisplaySetToRecommendedGPUChange">
+ Le impostazioni di visualizzazione sono ai livelli consigliati a causa di un cambiamento nella scheda grafica
+da &apos;[LAST_GPU]&apos;
+a &apos;[THIS_GPU]&apos;
+ </notification>
+ <notification name="DisplaySetToRecommendedFeatureChange">
+ Le impostazioni di visualizzazione sono ai livelli consigliati a causa di un cambiamento nel sottosistema di rendering.
</notification>
<notification name="ErrorMessage">
[ERROR_MESSAGE]
@@ -1432,7 +1437,7 @@ Per installare l&apos;aggiornamento è necessario riavviare [APP_NAME].
<usetemplate ignoretext="Conferma prima di restituire gli oggetti ai relativi proprietari" name="okcancelignore" notext="Annulla" yestext="OK"/>
</notification>
<notification name="GroupLeaveConfirmMember">
- Sei attualmente un membro del gruppo [GROUP].
+ Sei attualmente un membro del gruppo &lt;nolink&gt;[GROUP]&lt;/nolink&gt;.
Vuoi lasciare il gruppo?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
@@ -1916,7 +1921,13 @@ Trasferisci gli elementi nell&apos;inventario?
<usetemplate ignoretext="Conferma prima di uscire" name="okcancelignore" notext="Non uscire" yestext="Esci"/>
</notification>
<notification name="ConfirmRestoreToybox">
- Passare ai pulsanti e alle barre strumenti predefinite?
+ Questa azione ripristina pulsanti e barre degli strumenti predefinite.
+
+Questa azione non può essere ripristinata
+ <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
+ </notification>
+ <notification name="ConfirmClearAllToybox">
+ Questa azione riporterà tutti i pulsanti nella casella strumenti. Le barre degli strumenti saranno vuote.
Questa azione non può essere ripristinata
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
@@ -2125,10 +2136,10 @@ Verrà avviato il browser Web.
Oggetto: [SUBJECT], Messaggio: [MESSAGE]
</notification>
<notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; è Online
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; è online
</notification>
<notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; è Offline
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; è offline
</notification>
<notification name="AddSelfFriend">
Anche se sei molto simpatico, non puoi aggiungere te stesso all&apos;elenco degli amici.
@@ -2241,14 +2252,16 @@ Seleziona solo un oggetto.
Il tuo biglietto da visita non è stato accettato.
</notification>
<notification name="TeleportToLandmark">
- Puoi teleportarti alle ubicazioni come &apos;[NAME]&apos; aprendo il pannello Luoghi sul lato destro dello schermo, quindi selezionare la scheda Punti di riferimento.
-Clicca su un punto di riferimento per selezionarlo, quindi clicca su Teleport sul lato inferiore del pannello.
-(Puoi anche fare doppio clic sul punto di riferimento oppure cliccare su di esso con il tasto destro del mouse e scegliere Teleport.)
+ Per teleportarti a luoghi come &apos;[NAME]&apos;, clicca sul pulsante &quot;Luoghi&quot;,
+ quindi seleziona la scheda Punti di riferimento nel pannello che viene aperto. Clicca su qualsiasi
+ unto di riferimento per selezionarlo, quindi clicca su Teleport sul lato inferiore del pannello.
+ (Puoi anche fare doppio clic sul punto di riferimento oppure cliccare su di esso con il tasto destro del mouse e
+ scegliere Teleport.)
</notification>
<notification name="TeleportToPerson">
- Puoi contattare il residente &apos;[NAME]&apos; aprendo il pannello Persone nel lato destro del tuo schermo.
-Seleziona il residente dall&apos;elenco, clicca su &apos;IM&apos; in basso nel pannello.
-(Puoi anche fare doppio clic sul nome nell&apos;elenco oppure fare clic con il pulsante destro del mouse e selezionare &apos;IM&apos;).
+ Per contattare Residenti come &apos;[NAME]&apos;, clicca sul pulsante &quot;Persone&quot;, seleziona un Residente nel pannello che viene aperto, quindi clicca su &apos;IM&apos; in
+ basso nel pannello.
+ (Puoi anche fare doppio clic sul nome nell&apos;elenco oppure fare clic con il pulsante destro del mouse e selezionare &apos;IM&apos;).
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Non è possibile selezionare il terreno attraverso i confini del server.
@@ -2269,6 +2282,9 @@ Prova a selezionare una parte di terreno più piccola.
<notification name="PaymentSent">
[MESSAGE]
</notification>
+ <notification name="PaymentFailure">
+ [MESSAGE]
+ </notification>
<notification name="EventNotification">
Notifica eventi:
@@ -2520,10 +2536,10 @@ Riprova tra qualche istante.
</form>
</notification>
<notification name="FriendshipAccepted">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; ha accettato la tua offerta di amicizia.
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; ha accettato la tua richiesta di amicizia.
</notification>
<notification name="FriendshipDeclined">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; ha rifiutato la tua offerta di amicizia.
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; ha rifiutato la tua richiesta di amicizia.
</notification>
<notification name="FriendshipAcceptedByMe">
Offerta di amicizia accettata.
@@ -2800,7 +2816,7 @@ Per informazioni dettagliate, vedi il file del registro.
Con i seguenti residenti?
[RESIDENTS]
- <usetemplate name="okcancelbuttons" notext="Annulla" yestext="Ok"/>
+ <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
<notification name="ItemsShared">
Gli oggetti sono stati condivisi.
@@ -2890,7 +2906,7 @@ In questo modo verrà disattivato l&apos;audio anche di tutti i residenti che si
uniscono alla chiamata in un secondo momento, anche dopo che tu ti fossi scollegato.
Disattiva audio di tutti?
- <usetemplate ignoretext="Conferma prima di disattivare l&apos;audio di tutti i partecipanti alla chiamata di gruppo" name="okcancelignore" notext="Annulla" yestext="Ok"/>
+ <usetemplate ignoretext="Conferma prima di disattivare l&apos;audio di tutti i partecipanti alla chiamata di gruppo" name="okcancelignore" notext="Annulla" yestext="OK"/>
</notification>
<notification label="Chat" name="HintChat">
Per partecipare alla conversazione, digita nel campo chat in basso.
diff --git a/indra/newview/skins/default/xui/it/panel_edit_skin.xml b/indra/newview/skins/default/xui/it/panel_edit_skin.xml
index a15489b333..466eff2708 100644
--- a/indra/newview/skins/default/xui/it/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_skin.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skin_panel">
<panel name="avatar_skin_color_panel">
- <texture_picker label="Tatuaggi testa" name="Head Tattoos" tool_tip="Clicca per scegliere una fotografia"/>
- <texture_picker label="Tatuaggi superiori" name="Upper Tattoos" tool_tip="Clicca per scegliere una fotografia"/>
- <texture_picker label="Tatuaggi inferiori" name="Lower Tattoos" tool_tip="Clicca per scegliere una fotografia"/>
+ <texture_picker label="Testa" name="Head" tool_tip="Clicca per scegliere una fotografia"/>
+ <texture_picker label="Parte superiore del corpo" name="Upper Body" tool_tip="Clicca per scegliere una fotografia"/>
+ <texture_picker label="Parte inferiore del corpo" name="Lower Body" tool_tip="Clicca per scegliere una fotografia"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/it/panel_postcard_message.xml b/indra/newview/skins/default/xui/it/panel_postcard_message.xml
new file mode 100644
index 0000000000..c720f4822d
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_postcard_message.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_message">
+ <text name="to_label">
+ A:
+ </text>
+ <text name="name_label">
+ Da:
+ </text>
+ <text name="subject_label">
+ Oggetto:
+ </text>
+ <line_editor label="Digita qui l&apos;oggetto." name="subject_form"/>
+ <text name="msg_label">
+ Messaggio:
+ </text>
+ <text_editor name="msg_form">
+ Digita qui il messaggio.
+ </text_editor>
+ <button label="Annulla" name="cancel_btn"/>
+ <button label="Invia" name="send_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_postcard_settings.xml b/indra/newview/skins/default/xui/it/panel_postcard_settings.xml
new file mode 100644
index 0000000000..6a586c4415
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_postcard_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_settings">
+ <combo_box label="Risoluzione" name="postcard_size_combo">
+ <combo_box.item label="Finestra attuale" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Personalizza" name="Custom"/>
+ </combo_box>
+ <layout_stack name="postcard_image_params_ls">
+ <layout_panel name="postcard_image_size_lp">
+ <spinner label="Larghezza" name="postcard_snapshot_width"/>
+ <spinner label="Altezza" name="postcard_snapshot_height"/>
+ <check_box label="Mantieni le proporzioni" name="postcard_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="postcard_image_format_quality_lp">
+ <slider label="Qualità dell&apos;immagine" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
index 1a0a1d8434..7f5992b584 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
@@ -29,30 +29,5 @@
<check_box label="Chat IM" name="EnableIMChatPopups" tool_tip="Seleziona per vedere una finestra popup quando arriva un messaggio IM"/>
<spinner label="Durata chat vicine:" name="nearby_toasts_lifetime"/>
<spinner label="Durata dissolvenza chat vicine:" name="nearby_toasts_fadingtime"/>
- <check_box label="Use machine translation while chatting" name="translate_chat_checkbox"/>
- <text name="translate_chb_label">
- Usa la traduzione meccanica durante le chat
- </text>
- <text name="translate_language_text" width="110">
- Traduci chat in:
- </text>
- <combo_box name="translate_language_combobox" width="146">
- <combo_box.item label="Default di sistema" name="System Default Language"/>
- <combo_box.item label="English (Inglese)" name="English"/>
- <combo_box.item label="Dansk (Danese)" name="Danish"/>
- <combo_box.item label="Deutsch (Tedesco)" name="German"/>
- <combo_box.item label="Español (Spagnolo)" name="Spanish"/>
- <combo_box.item label="Français (Francese)" name="French"/>
- <combo_box.item label="Italiano" name="Italian"/>
- <combo_box.item label="Magyar (Ungherese)" name="Hungarian"/>
- <combo_box.item label="Nederlands (Olandese)" name="Dutch"/>
- <combo_box.item label="Polski (Polacco)" name="Polish"/>
- <combo_box.item label="Português (Portoghese)" name="Portugese"/>
- <combo_box.item label="Русский (Russo)" name="Russian"/>
- <combo_box.item label="Türkçe (Turco)" name="Turkish"/>
- <combo_box.item label="Українська (Ucraino)" name="Ukrainian"/>
- <combo_box.item label="中文 (正體) (Cinese)" name="Chinese"/>
- <combo_box.item label="日本語 (Giapponese)" name="Japanese"/>
- <combo_box.item label="한국어 (Coreano)" name="Korean"/>
- </combo_box>
+ <button label="Impostazioni traduzione chat" name="ok_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
index bf78432110..0189d47f45 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
@@ -15,7 +15,7 @@
Web:
</text>
<radio_group name="use_external_browser">
- <radio_item label="Usa il mio browser (IE, Firefox, Safari)" name="external" tool_tip="Utilizza il browser Web predefinito di sistema per l&apos;aiuto, per i link Web e così via. Sconsigliato durante l&apos;esecuzione a tutto schermo." value="1"/>
+ <radio_item label="Usa il mio browser (IE, Firefox, Safari)" name="external" tool_tip="Utilizza il browser Web predefinito di sistema per l&apos;aiuto, per i link Web e così via. Sconsigliato durante l&apos;esecuzione a tutto schermo." value="true"/>
<radio_item label="Utilizza il browser Web integrato" name="internal" tool_tip="Utilizza il browser Web integrato per l&apos;aiuto, per i link Web e così via. Questo browser si apre in una nuova finestra in [APP_NAME]." value=""/>
</radio_group>
<check_box initial_value="true" label="Abilita plugin" name="browser_plugins_enabled"/>
diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml
new file mode 100644
index 0000000000..c9245029b7
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_inventory">
+ <text name="title">
+ Salva nell&apos;inventario
+ </text>
+ <text name="hint_lbl">
+ Salvare un&apos;immagine nell&apos;inventario costa L$[UPLOAD_COST]. Per salvare l&apos;immagine come texture, selezionare uno dei formati quadrati.
+ </text>
+ <combo_box label="Risoluzione" name="texture_size_combo">
+ <combo_box.item label="Finestra attuale" name="CurrentWindow"/>
+ <combo_box.item label="Piccola (128x128)" name="Small(128x128)"/>
+ <combo_box.item label="Media (256x256)" name="Medium(256x256)"/>
+ <combo_box.item label="Grande (512x512)" name="Large(512x512)"/>
+ <combo_box.item label="Personalizza" name="Custom"/>
+ </combo_box>
+ <spinner label="Larghezza" name="inventory_snapshot_width"/>
+ <spinner label="Altezza" name="inventory_snapshot_height"/>
+ <check_box label="Mantieni le proporzioni" name="inventory_keep_aspect_check"/>
+ <button label="Annulla" name="cancel_btn"/>
+ <button label="Salva" name="save_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_local.xml b/indra/newview/skins/default/xui/it/panel_snapshot_local.xml
new file mode 100644
index 0000000000..4b725b68f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_snapshot_local.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_local">
+ <text name="title">
+ Salva sul mio computer
+ </text>
+ <combo_box label="Risoluzione" name="local_size_combo">
+ <combo_box.item label="Finestra attuale" name="CurrentWindow"/>
+ <combo_box.item label="320x240" name="320x240"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="1280x1024" name="1280x1024"/>
+ <combo_box.item label="1600x1200" name="1600x1200"/>
+ <combo_box.item label="Personalizza" name="Custom"/>
+ </combo_box>
+ <layout_stack name="local_image_params_ls">
+ <layout_panel name="local_image_size_lp">
+ <spinner label="Larghezza" name="local_snapshot_width"/>
+ <spinner label="Altezza" name="local_snapshot_height"/>
+ <check_box label="Mantieni le proporzioni" name="local_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="local_image_format_quality_lp">
+ <combo_box label="Formato" name="local_format_combo">
+ <combo_box.item label="PNG (senza perdite)" name="PNG"/>
+ <combo_box.item label="JPEG" name="JPEG"/>
+ <combo_box.item label="BMP (senza perdite)" name="BMP"/>
+ </combo_box>
+ <slider label="Qualità dell&apos;immagine" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <button label="Annulla" name="cancel_btn"/>
+ <flyout_button label="Salva" name="save_btn" tool_tip="Salva immagine come file">
+ <flyout_button.item label="Salva" name="save_item"/>
+ <flyout_button.item label="Salva con nome..." name="saveas_item"/>
+ </flyout_button>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_options.xml b/indra/newview/skins/default/xui/it/panel_snapshot_options.xml
new file mode 100644
index 0000000000..f2d42c5197
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_snapshot_options.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_options">
+ <button label="Invia post al feed del mio profilo" name="save_to_profile_btn"/>
+ <button label="E-mail" name="save_to_email_btn"/>
+ <button label="Salva nell&apos;inventario (L$[AMOUNT])" name="save_to_inventory_btn"/>
+ <button label="Salva sul mio computer" name="save_to_computer_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml
new file mode 100644
index 0000000000..3703b97e6c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_postcard">
+ <string name="default_subject">
+ Cartolina da [SECOND_LIFE].
+ </string>
+ <string name="default_message">
+ Dai un&apos;occhiata!
+ </string>
+ <string name="upload_message">
+ Invio...
+ </string>
+ <text name="title">
+ E-mail
+ </text>
+ <button label="Messaggio" name="message_btn"/>
+ <button label="Impostazioni" name="settings_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/it/panel_snapshot_profile.xml
new file mode 100644
index 0000000000..2cdbf97049
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_snapshot_profile.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_profile">
+ <text name="title">
+ Invia post al feed del mio profilo
+ </text>
+ <combo_box label="Risoluzione" name="profile_size_combo">
+ <combo_box.item label="Finestra attuale" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Personalizza" name="Custom"/>
+ </combo_box>
+ <layout_stack name="profile_image_params_ls">
+ <layout_panel name="profile_image_size_lp">
+ <spinner label="Larghezza" name="profile_snapshot_width"/>
+ <spinner label="Altezza" name="profile_snapshot_height"/>
+ <check_box label="Mantieni le proporzioni" name="profile_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="profile_image_metadata_lp">
+ <text name="caption_label">
+ Didascalia:
+ </text>
+ <check_box initial_value="true" label="Includi luogo" name="add_location_cb"/>
+ </layout_panel>
+ </layout_stack>
+ <button label="Annulla" name="cancel_btn"/>
+ <button label="Post" name="post_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_status_bar.xml b/indra/newview/skins/default/xui/it/panel_status_bar.xml
index fadaa575ea..4abc90113f 100644
--- a/indra/newview/skins/default/xui/it/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_status_bar.xml
@@ -18,7 +18,7 @@
<panel name="balance_bg">
<text name="balance" tool_tip="Clicca per aggiornare il tuo saldo in L$" value="L$ 20"/>
<button label="Acquista L$" name="buyL" tool_tip="Clicca per acquistare più L$"/>
- <button label="Acquisti" name="goShop" tool_tip="Apri Mercato Second Life"/>
+ <button label="Acquisti" name="goShop" tool_tip="Apri Mercato Second Life" width="75"/>
</panel>
<text name="TimeText" tool_tip="Orario attuale (Pacifico)">
24:00, ora del Pacifico
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 8f29233825..c81dd0f55d 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -1205,7 +1205,7 @@ Prova ad accedere nuovamente tra un minuto.
Non hai una copia di questa texture nel tuo inventario
</string>
<string name="InventoryInboxNoItems">
- Gli elementi acquistati attraverso il mercato verranno consegnati qui
+ Quando acquisti o ricevi un oggetto, verrà visualizzato qui per permetterti di trascinarlo in una cartella dell&apos;inventario o di cancellarlo se non desideri mantenerlo.
</string>
<string name="MarketplaceURL">
http://marketplace.[DOMAIN_NAME]/learn_more
@@ -1397,6 +1397,9 @@ Prova ad accedere nuovamente tra un minuto.
<string name="no_attachments">
Nessun allegato indossato
</string>
+ <string name="Attachments remain">
+ Allegati ([COUNT] spazi restanti)
+ </string>
<string name="Buy">
Acquista
</string>
@@ -1523,6 +1526,12 @@ Prova ad accedere nuovamente tra un minuto.
<string name="Right Pec">
Petto destro
</string>
+ <string name="Neck">
+ Collo
+ </string>
+ <string name="Avatar Center">
+ Centro avatar
+ </string>
<string name="Invalid Attachment">
Punto di collegamento non valido
</string>
@@ -3940,6 +3949,18 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
<string name="you_paid_ldollars_no_name">
Hai pagato L$ [AMOUNT] [REASON].
</string>
+ <string name="you_paid_failure_ldollars">
+ Non hai pagato [NAME] L$[AMOUNT] [REASON].
+ </string>
+ <string name="you_paid_failure_ldollars_no_info">
+ Non hai pagato L$ [AMOUNT].
+ </string>
+ <string name="you_paid_failure_ldollars_no_reason">
+ Non hai pagato [NAME] L$[AMOUNT].
+ </string>
+ <string name="you_paid_failure_ldollars_no_name">
+ Non hai pagato L$ [AMOUNT] [REASON].
+ </string>
<string name="for item">
per [ITEM]
</string>
@@ -4350,6 +4371,12 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="ExternalEditorFailedToRun">
L&apos;editor esterno non è stato avviato.
</string>
+ <string name="TranslationFailed">
+ Traduzione non riuscita: [REASON]
+ </string>
+ <string name="TranslationResponseParseError">
+ Errore di elaborazione della risposta della traduzione.
+ </string>
<string name="Esc">
Esc
</string>
@@ -4720,7 +4747,7 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
Mini mappa
</string>
<string name="Command_Move_Label">
- Movimento
+ Cammina / corri / vola
</string>
<string name="Command_People_Label">
Persone
@@ -4747,10 +4774,10 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
Parla
</string>
<string name="Command_View_Label">
- Visuale
+ Controlli fotocamera
</string>
<string name="Command_Voice_Label">
- Voce vicina
+ Impostazioni voce
</string>
<string name="Command_AboutLand_Tooltip">
Informazioni sul terreno che visiti
@@ -4822,7 +4849,16 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
Modifica angolo fotocamera
</string>
<string name="Command_Voice_Tooltip">
- Persona vicine con funzioni voce
+ I controlli per il volume per le chiamate e per le persone nelle vicinanze nel mondo virtuale
+ </string>
+ <string name="Toolbar_Bottom_Tooltip">
+ attualmente nella barra degli strumenti in basso
+ </string>
+ <string name="Toolbar_Left_Tooltip">
+ attualmente nella barra degli strumenti a sinistra
+ </string>
+ <string name="Toolbar_Right_Tooltip">
+ attualmente nella barra degli strumenti a destra
</string>
<string name="Retain%">
Mantieni%
@@ -4848,4 +4884,19 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="Normal">
Normale
</string>
+ <string name="snapshot_quality_very_low">
+ Molto basso
+ </string>
+ <string name="snapshot_quality_low">
+ Basso
+ </string>
+ <string name="snapshot_quality_medium">
+ Medio
+ </string>
+ <string name="snapshot_quality_high">
+ Alto
+ </string>
+ <string name="snapshot_quality_very_high">
+ Molto alto
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/it/teleport_strings.xml b/indra/newview/skins/default/xui/it/teleport_strings.xml
index a0b324d8fb..f485212290 100644
--- a/indra/newview/skins/default/xui/it/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/it/teleport_strings.xml
@@ -19,8 +19,8 @@ Se si continua a visualizzare questo messaggio, consulta la pagina [SUPPORT_SITE
Spiacenti, il sistema non riesce a completare il teletrasporto. Riprova tra un attimo.
</message>
<message name="NoHelpIslandTP">
- Non è possibile per te ritornare all&apos;Welcome Island.
-Vai alla &apos;Welcome Island Public&apos; per ripetere il tutorial.
+ Non puoi teleportarti nuovamente a Welcome Island.
+Per ripetere l&apos;esercitazione, visita &apos;Welcome Island Public&apos;.
</message>
<message name="noaccess_tport">
Spiacenti, ma non hai accesso nel luogo di destinazione richiesto.
diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml
index c628ade43e..3c7a210a22 100644
--- a/indra/newview/skins/default/xui/ja/floater_about.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about.xml
@@ -90,6 +90,8 @@ google-perftools Copyright (c) 2005, Google Inc.
Second Life ビューワでは Havok (TM) Physics が使用されています。(c)Copyright 1999-2010 Havok.com Inc. (and its Licensors).無断複写・複製・転載を禁じます。詳細については www.havok.com をご参照ください。
+このソフトウェアには、NVIDIA Corporation によるソースコードが含まれます。
+
無断複写・複製・転載を禁じます。詳細については licenses.txt をご参照ください。
ボイスチャットのオーディオコーディング:Polycom(R) Siren14(TM) (ITU-T Rec.G.722.1 Annex C)
diff --git a/indra/newview/skins/default/xui/ja/floater_about_land.xml b/indra/newview/skins/default/xui/ja/floater_about_land.xml
index 3c88c902f8..816a6ff203 100644
--- a/indra/newview/skins/default/xui/ja/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about_land.xml
@@ -130,7 +130,7 @@
交通量:
</text>
<text name="DwellText">
- 誤
+ ローディング...
</text>
<button label="土地の購入" label_selected="土地を購入..." left="130" name="Buy Land..." width="100"/>
<button label="リンデンセール" label_selected="Linden セール..." name="Linden Sale..." tool_tip="土地が所有されており、コンテンツが設定されている必要があります。オークションの対象になっていないことも必要条件です。"/>
@@ -311,13 +311,15 @@
プッシュ禁止 (地域設定優先)
</panel.string>
<panel.string name="see_avs_text">
- この区画にいる住人と会ってチャットする
+ 他の区画にいるアバターは、
</panel.string>
<text name="allow_label">
他の住人への許可:
</text>
- <check_box label="地形を編集" name="edit land check" tool_tip="チェックを入れると、他人があなたの土地の地形編集を行うことが可能となります。このオプションのチェックを外しておくことをおすすめします。外した状態であなたの土地の地形編集が可能です。"/>
- <check_box label="飛行" name="check fly" tool_tip="チェックを入れるとこの土地での飛行が可能となります。チェックを外すと土地に入る際と通り過ぎるときのみ飛行可能となります。"/>
+ <text name="allow_label0">
+ 飛行:
+ </text>
+ <check_box label="全員" name="check fly" tool_tip="チェックを入れるとこの土地での飛行が可能となります。チェックを外すと土地に入る際と通り過ぎるときのみ飛行可能となります。"/>
<text name="allow_label2">
制作:
</text>
@@ -333,9 +335,6 @@
</text>
<check_box label="全員" name="check other scripts"/>
<check_box label="グループ" name="check group scripts"/>
- <text name="land_options_label">
- 土地オプション:
- </text>
<check_box label="安全(ダメージなし)" name="check safe" tool_tip="チェックを入れるとこの土地でのダメージコンバットが無効になり、「安全」に設定されます。 チェックを外すとダメージコンバットが有効になります。"/>
<check_box label="プッシュ禁止" name="PushRestrictCheck" tool_tip="スクリプトによるプッシュを禁止します。 このオプションを選択することにより、あなたの土地での破壊的行動を防ぐことができます。"/>
<check_box label="検索に区画を表示(週 L$ 30)" name="ShowDirectoryCheck" tool_tip="この区画を検索結果に表示します"/>
@@ -376,9 +375,9 @@
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="写真をクリックして選択"/>
<text name="allow_label5">
- 他の区画にいる住人への許可:
+ この区画にいるアバターに会ってチャットできます
</text>
- <check_box label="アバターを表示" name="SeeAvatarsCheck" tool_tip="他の区画の住人が、この区画にいる住人に会ってチャットすることを許可し、あなたもそれら住人に会ってチャットできるようにします。"/>
+ <check_box label="アバターを表示" name="SeeAvatarsCheck" tool_tip="他の区画のアバターが、この区画にいるアバターに会ってチャットすることを許可し、あなたもそれらアバターに会ってチャットできるようにします。"/>
<text name="landing_point">
着地点: [LANDING]
</text>
diff --git a/indra/newview/skins/default/xui/ja/floater_avatar.xml b/indra/newview/skins/default/xui/ja/floater_avatar.xml
index c4455282d2..d289580506 100644
--- a/indra/newview/skins/default/xui/ja/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/ja/floater_avatar.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Avatar" title="アバターピッカー"/>
+<floater name="Avatar" title="アバターを選択"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_buy_currency.xml b/indra/newview/skins/default/xui/ja/floater_buy_currency.xml
index e447eefe0e..a472f163e3 100644
--- a/indra/newview/skins/default/xui/ja/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/ja/floater_buy_currency.xml
@@ -46,7 +46,7 @@
L$ [AMT]
</text>
<text name="currency_links">
- [http://www.secondlife.com/my/account/payment_method_management.php?lang=ja-JP 支払方法] | [http://www.secondlife.com/my/account/currency.php?lang=ja-JP 通貨]
+ [http://www.secondlife.com/my/account/payment_method_management.php 支払方法] | [http://www.secondlife.com/my/account/currency.php 通貨]
</text>
<text name="exchange_rate_note">
金額を再入力して最新換算レートを確認します。
diff --git a/indra/newview/skins/default/xui/ja/floater_camera.xml b/indra/newview/skins/default/xui/ja/floater_camera.xml
index 0661e17309..982e5ce42b 100644
--- a/indra/newview/skins/default/xui/ja/floater_camera.xml
+++ b/indra/newview/skins/default/xui/ja/floater_camera.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="camera_floater" title="表示">
+<floater name="camera_floater" title="カメラのコントロール">
<floater.string name="rotate_tooltip">
フォーカスを中心にカメラを回転
</floater.string>
diff --git a/indra/newview/skins/default/xui/ja/floater_chat_bar.xml b/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
index 9735afb101..504cea5931 100644
--- a/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="chat_bar" title="近くのチャット">
- <panel>
+ <panel name="bottom_panel">
<line_editor label="ここをクリックしてチャットを開始します。" name="chat_box" tool_tip="Enter キーを押して話し、Ctrl + Enter キーで叫びます。"/>
<button name="show_nearby_chat" tool_tip="近くのチャットログを表示・非表示"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml b/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml
index ffafbaf3b6..1b6558a9eb 100644
--- a/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml
@@ -4,8 +4,8 @@
フィルタリング:
</text>
<check_box label="異方的フィルタリング(有効にすると速度が低下します)" name="ani"/>
- <text name="Antialiasing:">
- アンチエイリアシング:
+ <text name="antialiasing label">
+ アンチエイリアシング:
</text>
<combo_box label="アンチエイリアシング" name="fsaa">
<combo_box.item label="無効" name="FSAADisabled"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_model_preview.xml b/indra/newview/skins/default/xui/ja/floater_model_preview.xml
index 157c68a570..c9ff0e29cb 100644
--- a/indra/newview/skins/default/xui/ja/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_model_preview.xml
@@ -4,6 +4,9 @@
<string name="status_parse_error">
エラー:Dae に問題が見つかりました - 詳細についてはログをご参照ください。
</string>
+ <string name="status_material_mismatch">
+ エラー:モデルの材料は参考モデルのサブセットではありません。
+ </string>
<string name="status_reading_file">
ローディング...
</string>
diff --git a/indra/newview/skins/default/xui/ja/floater_model_wizard.xml b/indra/newview/skins/default/xui/ja/floater_model_wizard.xml
index 915b37557f..6aaa9a42a5 100644
--- a/indra/newview/skins/default/xui/ja/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/ja/floater_model_wizard.xml
@@ -20,6 +20,9 @@
アップロードするモデルファイルの選択
</text>
<button label="参照" label_selected="参照" name="browse"/>
+ <text name="Model types">
+ Second Life は COLLADA (.dae) ファイルをサポートします。
+ </text>
<text name="dimensions">
X Y Z
</text>
diff --git a/indra/newview/skins/default/xui/ja/floater_moveview.xml b/indra/newview/skins/default/xui/ja/floater_moveview.xml
index 88c1905b8a..aed3b78a14 100644
--- a/indra/newview/skins/default/xui/ja/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_moveview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="move_floater" title="移動">
+<floater name="move_floater" title="歩行 / 走行 / 飛行">
<string name="walk_forward_tooltip">
前に進む(上矢印か W を押す)
</string>
diff --git a/indra/newview/skins/default/xui/ja/floater_snapshot.xml b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
index 05a10f9f6d..cf4732a68e 100644
--- a/indra/newview/skins/default/xui/ja/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
@@ -3,73 +3,63 @@
<floater.string name="unknown">
不明
</floater.string>
- <radio_group label="スナップショットの種類" name="snapshot_type_radio">
- <radio_item label="メール" name="postcard"/>
- <radio_item label="持ち物(L$[AMOUNT])" name="texture"/>
- <radio_item label="コンピューターに保存" name="local"/>
- </radio_group>
+ <string name="postcard_progress_str">
+ メールの送信
+ </string>
+ <string name="profile_progress_str">
+ 投稿
+ </string>
+ <string name="inventory_progress_str">
+ 持ち物に保存
+ </string>
+ <string name="local_progress_str">
+ コンピュータに保存
+ </string>
+ <string name="profile_succeeded_str">
+ 画像がアップロードされました
+ </string>
+ <string name="postcard_succeeded_str">
+ メールが送信されました
+ </string>
+ <string name="inventory_succeeded_str">
+ 持ち物に保存されました
+ </string>
+ <string name="local_succeeded_str">
+ コンピュータに保存されました
+ </string>
+ <string name="profile_failed_str">
+ プロフィールフィードに画像をアップロードできませんでした。
+ </string>
+ <string name="postcard_failed_str">
+ メールを送信できませんでした。
+ </string>
+ <string name="inventory_failed_str">
+ 持ち物に保存できませんでした。
+ </string>
+ <string name="local_failed_str">
+ コンピュータに保存できませんでした。
+ </string>
+ <button name="advanced_options_btn" tool_tip="詳しい設定"/>
+ <text name="image_res_text">
+ [WIDTH] x [HEIGHT] px
+ </text>
<text name="file_size_label">
[SIZE] キロバイト
</text>
- <button label="スナップショットを更新" name="new_snapshot_btn"/>
- <button label="送信" name="send_btn"/>
- <button label="保存(L$[AMOUNT])" name="upload_btn"/>
- <flyout_button label="保存" name="save_btn" tool_tip="画像をファイルに保存">
- <flyout_button.item label="保存" name="save_item"/>
- <flyout_button.item label="別名で保存..." name="saveas_item"/>
- </flyout_button>
- <button label="詳細" name="more_btn" tool_tip="詳しい設定"/>
- <button label="簡易" name="less_btn" tool_tip="詳しい設定"/>
- <button label="取り消し" name="discard_btn"/>
- <text name="type_label2">
- サイズ
- </text>
- <text name="format_label">
- 書式
- </text>
- <combo_box label="解像度" name="postcard_size_combo">
- <combo_box.item label="現在のウィンドウ" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="カスタム" name="Custom"/>
- </combo_box>
- <combo_box label="解像度" name="texture_size_combo">
- <combo_box.item label="現在のウィンドウ" name="CurrentWindow"/>
- <combo_box.item label="小(128x128)" name="Small(128x128)"/>
- <combo_box.item label="中(256x256)" name="Medium(256x256)"/>
- <combo_box.item label="大(512x512)" name="Large(512x512)"/>
- <combo_box.item label="カスタム" name="Custom"/>
- </combo_box>
- <combo_box label="解像度" name="local_size_combo">
- <combo_box.item label="現在のウィンドウ" name="CurrentWindow"/>
- <combo_box.item label="320x240" name="320x240"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1280x1024" name="1280x1024"/>
- <combo_box.item label="1600x1200" name="1600x1200"/>
- <combo_box.item label="カスタム" name="Custom"/>
- </combo_box>
- <combo_box label="書式" name="local_format_combo">
- <combo_box.item label="PNG" name="PNG"/>
- <combo_box.item label="JPEG" name="JPEG"/>
- <combo_box.item label="BMP" name="BMP"/>
- </combo_box>
- <spinner label="幅" name="snapshot_width"/>
- <spinner label="高さ" name="snapshot_height"/>
- <check_box label="縦横比の固定" name="keep_aspect_check"/>
- <slider label="画質" name="image_quality_slider"/>
- <text name="layer_type_label">
- キャプチャ:
- </text>
- <combo_box label="画像レイヤー" name="layer_types">
- <combo_box.item label="色" name="Colors"/>
- <combo_box.item label="深度" name="Depth"/>
- </combo_box>
- <check_box label="インターフェース" name="ui_check"/>
- <check_box label="HUD" name="hud_check"/>
- <check_box label="保存後もこのまま" name="keep_open_check"/>
- <check_box label="画面全体を静止" name="freeze_frame_check"/>
- <check_box label="自動更新" name="auto_snapshot_check"/>
+ <panel name="advanced_options_panel">
+ <text name="advanced_options_label">
+ 詳しい設定
+ </text>
+ <text name="layer_type_label">
+ キャプチャ:
+ </text>
+ <combo_box label="画像レイヤー" name="layer_types">
+ <combo_box.item label="色" name="Colors"/>
+ <combo_box.item label="深度" name="Depth"/>
+ </combo_box>
+ <check_box label="インターフェース" name="ui_check"/>
+ <check_box label="HUD" name="hud_check"/>
+ <check_box label="画面全体を静止" name="freeze_frame_check"/>
+ <check_box label="自動更新" name="auto_snapshot_check"/>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_toybox.xml b/indra/newview/skins/default/xui/ja/floater_toybox.xml
index d7056f806c..682352ec82 100644
--- a/indra/newview/skins/default/xui/ja/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/ja/floater_toybox.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Toybox" title="ツールバーをカスタマイズ">
+<floater name="Toybox" title="ツールバーのボタン">
<text name="toybox label 1">
ボタンをツールバーに追加または削除するにはボタンをドラッグします。
</text>
<text name="toybox label 2">
各ツールバーの設定に応じて、ボタンは以下のように表示されたり、アイコンのみで表示されます。
</text>
+ <button label="ツールバーを全てクリア" label_selected="ツールバーを全てクリア" name="btn_clear_all"/>
<button label="デフォルト設定を復元" label_selected="デフォルト設定を復元" name="btn_restore_defaults"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_translation_settings.xml b/indra/newview/skins/default/xui/ja/floater_translation_settings.xml
new file mode 100644
index 0000000000..27143086ac
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_translation_settings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_translation_settings" title="チャットの翻訳設定">
+ <string name="bing_api_key_not_verified">
+ Bing appID を認証できませんでした。もう一度お試しください。
+ </string>
+ <string name="google_api_key_not_verified">
+ Google API キーを認証できませんでした。もう一度お試しください。
+ </string>
+ <string name="bing_api_key_verified">
+ Bing appID が認証されました。
+ </string>
+ <string name="google_api_key_verified">
+ Google API キーが認証されました。
+ </string>
+ <check_box label="チャット中の機械翻訳機能を有効にする" name="translate_chat_checkbox"/>
+ <text name="translate_language_label">
+ 翻訳する言語:
+ </text>
+ <combo_box name="translate_language_combo">
+ <combo_box.item label="システム標準" name="System Default Language"/>
+ <combo_box.item label="英語" name="English"/>
+ <combo_box.item label="Dansk(デンマーク語)" name="Danish"/>
+ <combo_box.item label="Deutsch(ドイツ語)" name="German"/>
+ <combo_box.item label="Español(スペイン語)" name="Spanish"/>
+ <combo_box.item label="Français(フランス語)" name="French"/>
+ <combo_box.item label="Italiano(イタリア語)" name="Italian"/>
+ <combo_box.item label="Magyar(ハンガリー語)" name="Hungarian"/>
+ <combo_box.item label="Nederlands(オランダ語)" name="Dutch"/>
+ <combo_box.item label="Polski(ポーランド語)" name="Polish"/>
+ <combo_box.item label="Português(ポルトガル語)" name="Portugese"/>
+ <combo_box.item label="Русский(ロシア語)" name="Russian"/>
+ <combo_box.item label="Türkçe(トルコ語)" name="Turkish"/>
+ <combo_box.item label="Українська (ウクライナ語)" name="Ukrainian"/>
+ <combo_box.item label="中文 (正體) (中国語)" name="Chinese"/>
+ <combo_box.item label="日本語(日本語)" name="Japanese"/>
+ <combo_box.item label="한국어(韓国語)" name="Korean"/>
+ </combo_box>
+ <text name="tip">
+ 翻訳サービスを選択してください:
+ </text>
+ <radio_group name="translation_service_rg">
+ <radio_item initial_value="bing" label="Bing Translator" name="bing"/>
+ <radio_item initial_value="google" label="Google Translate" name="google"/>
+ </radio_group>
+ <text name="bing_api_key_label">
+ Bing AppID [http://www.bing.com/developers/createapp.aspx AppID]:
+ </text>
+ <button label="認証" name="verify_bing_api_key_btn"/>
+ <text name="google_api_key_label">
+ Google API key [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API key]:
+ </text>
+ <button label="認証" name="verify_google_api_key_btn"/>
+ <text name="google_links_text">
+ [http://code.google.com/apis/language/translate/v2/pricing.html 価格] | [https://code.google.com/apis/console 統計]
+ </text>
+ <button label="OK" name="ok_btn"/>
+ <button label="取り消し" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_voice_controls.xml b/indra/newview/skins/default/xui/ja/floater_voice_controls.xml
index f12648f208..f7d3fd11e0 100644
--- a/indra/newview/skins/default/xui/ja/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/ja/floater_voice_controls.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_voice_controls" title="ボイスコントロール">
<string name="title_nearby">
- 近くのボイス
+ ボイス設定
</string>
<string name="title_group">
[GROUP] とグループコール
@@ -10,7 +10,7 @@
コンファレンスコール
</string>
<string name="title_peer_2_peer">
- [NAME] でコール
+ [NAME] とコール
</string>
<string name="no_one_near">
近くにボイスを有効にしている人はいません。
diff --git a/indra/newview/skins/default/xui/ja/menu_toolbars.xml b/indra/newview/skins/default/xui/ja/menu_toolbars.xml
index e911ca4a13..d5363a5131 100644
--- a/indra/newview/skins/default/xui/ja/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/ja/menu_toolbars.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Toolbars Popup">
- <menu_item_call label="ボタンを選択..." name="Chose Buttons"/>
+ <menu_item_call label="このボタンを削除" name="Remove button"/>
+ <menu_item_call label="ツールバーのボタン..." name="Choose Buttons"/>
<menu_item_check label="アイコンとラベル" name="icons_with_text"/>
<menu_item_check label="アイコンのみ" name="icons_only"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml
index 125e9bb226..ef3261f1d4 100644
--- a/indra/newview/skins/default/xui/ja/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu_bar name="Main Menu">
<menu label="ミー" name="Me">
- <menu_item_call label="マイアカウント..." name="Manage My Account">
- <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=ja"/>
- </menu_item_call>
<menu_item_call label="プロフィール..." name="Profile"/>
<menu_item_call label="容姿..." name="ChangeOutfit"/>
+ <menu_item_call label="アバターを選択..." name="Avatar Picker"/>
<menu_item_check label="持ち物..." name="Inventory"/>
- <menu_item_check label="ジェスチャー..." name="Gestures"/>
- <menu_item_check label="ボイス..." name="ShowVoice"/>
+ <menu_item_call label="新しい持ち物ウィンドウ" name="NewInventoryWindow"/>
+ <menu_item_call label="場所..." name="Places"/>
+ <menu_item_call label="ピック..." name="Picks"/>
+ <menu_item_call label="カメラコントロール..." name="Camera Controls"/>
<menu label="ムーブメント" name="Movement">
<menu_item_call label="座る" name="Sit Down Here"/>
<menu_item_check label="飛ぶ" name="Fly"/>
@@ -22,34 +22,39 @@
<menu_item_call label="管理者権限のリクエスト" name="Request Admin Options"/>
<menu_item_call label="管理者ステータス解除" name="Leave Admin Options"/>
<menu_item_call label="L$ の購入" name="Buy and Sell L$"/>
+ <menu_item_call label="マイアカウント..." name="Manage My Account">
+ <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=ja"/>
+ </menu_item_call>
<menu_item_call label="環境設定..." name="Preferences"/>
- <menu_item_call label="ツールバー..." name="Toolbars"/>
+ <menu_item_call label="ツールバーのボタン..." name="Toolbars"/>
<menu_item_call label="全てのコントロールを非表示にする" name="Hide UI"/>
<menu_item_call label="[APP_NAME] を終了" name="Quit"/>
</menu>
<menu label="コミュニケーション" name="Communicate">
+ <menu_item_check label="チャット..." name="Nearby Chat"/>
+ <menu_item_check label="話す" name="Speak"/>
+ <menu_item_check label="ボイス設定..." name="Nearby Voice"/>
+ <menu_item_check label="ボイスモーフィング..." name="ShowVoice"/>
+ <menu_item_check label="ジェスチャー..." name="Gestures"/>
<menu_item_call label="フレンド" name="My Friends"/>
- <menu_item_call label="所属グループ" name="My Groups"/>
- <menu_item_check label="近くのチャット" name="Nearby Chat"/>
+ <menu_item_call label="グループ" name="My Groups"/>
<menu_item_call label="近くにいる人" name="Active Speakers"/>
- <menu_item_check label="近くのボイス" name="Nearby Voice"/>
</menu>
<menu label="世界" name="World">
- <menu_item_check label="ミニマップ" name="Mini-Map"/>
+ <menu_item_call label="現在地をランドマーク" name="Create Landmark Here"/>
+ <menu_item_call label="行き先..." name="Destinations"/>
<menu_item_check label="世界地図" name="World Map"/>
+ <menu_item_check label="ミニマップ" name="Mini-Map"/>
<menu_item_check label="検索" name="Search"/>
+ <menu_item_call label="ホームにテレポート" name="Teleport Home"/>
+ <menu_item_call label="現在地をホームに設定" name="Set Home to Here"/>
<menu_item_call label="スナップショット" name="Take Snapshot"/>
- <menu_item_call label="現在地をランドマーク" name="Create Landmark Here"/>
- <menu label="場所のプロフィール" name="Land">
- <menu_item_call label="場所のプロフィール" name="Place Profile"/>
- <menu_item_call label="土地情報" name="About Land"/>
- <menu_item_call label="地域 / 不動産" name="Region/Estate"/>
- </menu>
+ <menu_item_call label="場所のプロフィール" name="Place Profile"/>
+ <menu_item_call label="土地情報" name="About Land"/>
+ <menu_item_call label="地域 / 不動産" name="Region/Estate"/>
+ <menu_item_call label="保有地..." name="My Land"/>
<menu_item_call label="この土地を購入" name="Buy Land"/>
- <menu_item_call label="自分の土地" name="My Land"/>
<menu label="表示" name="LandShow">
- <menu_item_check label="移動コントロール" name="Movement Controls"/>
- <menu_item_check label="カメラコントロール" name="Camera Controls"/>
<menu_item_check label="立入禁止ライン" name="Ban Lines"/>
<menu_item_check label="ビーコン(標識)" name="beacons"/>
<menu_item_check label="プロパティ境界線" name="Property Lines"/>
@@ -58,16 +63,15 @@
<menu_item_check label="区画プロパティ" name="Parcel Properties"/>
<menu_item_check label="アドバンスメニュー" name="Show Advanced Menu"/>
</menu>
- <menu_item_call label="ホームにテレポート" name="Teleport Home"/>
- <menu_item_call label="現在地をホームに設定" name="Set Home to Here"/>
<menu label="太陽" name="Environment Settings">
<menu_item_call label="日の出" name="Sunrise"/>
<menu_item_call label="正午" name="Noon"/>
<menu_item_call label="日没" name="Sunset"/>
<menu_item_call label="深夜" name="Midnight"/>
+ <menu_item_call label="リージョンの設定を使用" name="Use Region Settings"/>
</menu>
- <menu label="自然環境エディター" name="Enviroment Editor">
- <menu_item_call label="環境の設定..." name="Enviroment Settings"/>
+ <menu label="自然環境エディター" name="Environment Editor">
+ <menu_item_call label="自然環境の設定..." name="Environment Settings"/>
<menu label="水の事前設定" name="Water Presets">
<menu_item_call label="新しい事前設定..." name="new_water_preset"/>
<menu_item_call label="事前設定を編集..." name="edit_water_preset"/>
@@ -146,6 +150,7 @@
<menu_item_call label="やり直し" name="Redo"/>
</menu>
<menu label="ヘルプ" name="Help">
+ <menu_item_call label="ハウツー..." name="How To"/>
<menu_item_call label="[SECOND_LIFE] ヘルプ" name="Second Life Help"/>
<menu_item_call label="嫌がらせを報告する" name="Report Abuse"/>
<menu_item_call label="バグを報告する" name="Report Bug"/>
@@ -200,11 +205,10 @@
<menu_item_check label="Use Plugin Read Thread" name="Use Plugin Read Thread"/>
<menu_item_call label="グループキャッシュのクリア" name="ClearGroupCache"/>
<menu_item_check label="マウスの平滑化" name="Mouse Smoothing"/>
+ <menu_item_call label="リリースキー" name="Release Keys"/>
<menu label="ショートカット" name="Shortcuts">
<menu_item_call label="画像 (L$ [COST] )..." name="Upload Image"/>
<menu_item_check label="検索" name="Search"/>
- <menu_item_call label="キーをリリース" name="Release Keys"/>
- <menu_item_call label="UI のサイズをデフォルトに設定する" name="Set UI Size to Default"/>
<menu_item_check label="アドバンスメニューを表示 - レガシーのショートカット" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="ウィンドウを閉じる" name="Close Window"/>
<menu_item_call label="全てのウィンドウを閉じる" name="Close All Windows"/>
@@ -290,6 +294,7 @@
<menu_item_check label="光" name="Lights"/>
<menu_item_check label="骨組みの衝突判定" name="Collision Skeleton"/>
<menu_item_check label="レイキャスト" name="Raycast"/>
+ <menu_item_check label="風のベクトル" name="Wind Vectors"/>
<menu_item_check label="描画の詳細度" name="rendercomplexity"/>
<menu_item_check label="スカルプト" name="Sculpt"/>
</menu>
@@ -302,7 +307,6 @@
<menu_item_check label="光と影" name="Lighting and Shadows"/>
<menu_item_check label="太陽・月・プロジェクタからの影" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO と影の平滑化" name="SSAO and Shadow Smoothing"/>
- <menu_item_check label="グローバルイルミネーション(試験段階)" name="Global Illumination"/>
<menu_item_check label="GL デバッグ" name="Debug GL"/>
<menu_item_check label="経路をデバッグ" name="Debug Pipeline"/>
<menu_item_check label="自動アルファマスク(遅延)" name="Automatic Alpha Masks (deferred)"/>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index 7dfa6d2f7a..20468c8c2a 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -1144,8 +1144,13 @@ L$ は返金されません。
-safe オプションを指定したので、
表示設定はセーフレベルに設定されています。
</notification>
- <notification name="DisplaySetToRecommended">
- 表示設定は、あなたのシステム構成に基づいて推奨されたレベルに設定されています。
+ <notification name="DisplaySetToRecommendedGPUChange">
+ グラフィックの変更により、画面設定は推奨レベルに設定されました。
+&apos;[LAST_GPU]&apos; から
+&apos;[THIS_GPU]&apos; まで
+ </notification>
+ <notification name="DisplaySetToRecommendedFeatureChange">
+ レンダリングサブシステムの変更により、画面設定は推奨レベルに設定されました。
</notification>
<notification name="ErrorMessage">
[ERROR_MESSAGE]
@@ -1467,7 +1472,7 @@ http://secondlife.com/download から最新バージョンをダウンロード
<usetemplate ignoretext="オブジェクトを所有者に返却する前の確認" name="okcancelignore" notext="取り消し" yestext="OK"/>
</notification>
<notification name="GroupLeaveConfirmMember">
- 現在あなたは [GROUP] のメンバーです。
+ 現在あなたは &lt;nolink&gt;[GROUP]&lt;/nolink&gt; のメンバーです。
このグループを抜けますか?
<usetemplate name="okcancelbuttons" notext="取り消し" yestext="OK"/>
</notification>
@@ -1954,7 +1959,13 @@ Adult 専用リージョンに入るには、住人のアカウントが年齢
<usetemplate ignoretext="終了時の確認" name="okcancelignore" notext="終了しない" yestext="終了"/>
</notification>
<notification name="ConfirmRestoreToybox">
- デフォルトのボタンとツールバーを復元しますか?
+ この操作を実行すると、デフォルト設定のボタンとツールバーが復元されます。
+
+この操作は元に戻せません。
+ <usetemplate name="okcancelbuttons" notext="取り消し" yestext="OK"/>
+ </notification>
+ <notification name="ConfirmClearAllToybox">
+ この操作により、全てのボタンはツールボックスに戻り、ツールバーは空になります。
この操作は元に戻せません。
<usetemplate name="okcancelbuttons" notext="取り消し" yestext="OK"/>
@@ -2167,10 +2178,10 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
件名: [SUBJECT]、メッセージ: [MESSAGE]
</notification>
<notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; はオンライン中です
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; はオンラインです
</notification>
<notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; はオフライン中です
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; はオフラインです
</notification>
<notification name="AddSelfFriend">
残念ながら自分自身をフレンド登録することはできません。
@@ -2284,13 +2295,15 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
コーリングカードが拒否されました。
</notification>
<notification name="TeleportToLandmark">
- 画面右の「場所」パネルを開いて、「ランドマーク」タブを選ぶと、[NAME] といった場所にテレポートできます。
-好きなランドマークをクリックして選び、次にパネル下の「テレポート」をクリックします。
-(ランドマークをダブルクリック、または右クリックして「テレポート」を選んでも同じです。)
+ [NAME] などの場所にテレポートするには、「場所」ボタンをクリックしてから、
+表示されたウィンドウで「ランドマーク」タブを選択します。ランドマークを
+いずれか 1 つ選択してから、ウィンドウ下部にある「テレポート」をクリックします。
+(この操作は、ランドマークをダブルクリックするか、右クリックして
+「テレポート」を選択して実行することもできます。)
</notification>
<notification name="TeleportToPerson">
- 画面右の「人」パネルを開いて、[NAME] といった住人に連絡を取ることができます。
-リストから住人を選択して、パネル下の「IM」をクリックします。
+ [NAME] のような住人に連絡をとるには、「人」ボタンをクリックし、表示されるウィンドウで「住人」を選択してから、
+ウィンドウ下部にある「IM」をクリックします。
(リストの名前をダブルクリック、または右クリックして「IM」を選んでも同じです。)
</notification>
<notification name="CantSelectLandFromMultipleRegions">
@@ -2312,6 +2325,9 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
<notification name="PaymentSent">
[MESSAGE]
</notification>
+ <notification name="PaymentFailure">
+ [MESSAGE]
+ </notification>
<notification name="EventNotification">
イベント通知:
@@ -2567,10 +2583,10 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
</form>
</notification>
<notification name="FriendshipAccepted">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt;は、フレンド登録を受け入れました。
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; はあなたからの友人登録リクエストを受諾しました。
</notification>
<notification name="FriendshipDeclined">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt;は、フレンド登録を断りました。
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; はあなたからの友人登録リクエストを拒否しました。
</notification>
<notification name="FriendshipAcceptedByMe">
フレンドの登録依頼が承認されました。
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_skin.xml b/indra/newview/skins/default/xui/ja/panel_edit_skin.xml
index 2c554dad94..7573132576 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_skin.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skin_panel">
<panel name="avatar_skin_color_panel">
- <texture_picker label="頭部のタトゥー" name="Head Tattoos" tool_tip="クリックして写真を選択"/>
- <texture_picker label="上部のタトゥー" name="Upper Tattoos" tool_tip="クリックして写真を選択"/>
- <texture_picker label="下部のタトゥー" name="Lower Tattoos" tool_tip="クリックして写真を選択"/>
+ <texture_picker label="頭" name="Head" tool_tip="クリックして写真を選択します"/>
+ <texture_picker label="上半身" name="Upper Body" tool_tip="クリックして写真を選択します"/>
+ <texture_picker label="下半身" name="Lower Body" tool_tip="クリックして写真を選択します"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/ja/panel_postcard_message.xml b/indra/newview/skins/default/xui/ja/panel_postcard_message.xml
new file mode 100644
index 0000000000..b7c3f48557
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_postcard_message.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_message">
+ <text name="to_label">
+ 終:
+ </text>
+ <text name="name_label">
+ 始:
+ </text>
+ <text name="subject_label">
+ 件名:
+ </text>
+ <line_editor label="件名をここに入力してください。" name="subject_form"/>
+ <text name="msg_label">
+ メッセージ:
+ </text>
+ <text_editor name="msg_form">
+ メッセージをここに入力してください。
+ </text_editor>
+ <button label="取り消し" name="cancel_btn"/>
+ <button label="送信" name="send_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml b/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml
new file mode 100644
index 0000000000..314aaef7fd
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_settings">
+ <combo_box label="解像度" name="postcard_size_combo">
+ <combo_box.item label="現在のウィンドウ" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="カスタム" name="Custom"/>
+ </combo_box>
+ <layout_stack name="postcard_image_params_ls">
+ <layout_panel name="postcard_image_size_lp">
+ <spinner label="幅" name="postcard_snapshot_width"/>
+ <spinner label="高さ" name="postcard_snapshot_height"/>
+ <check_box label="縦横比の固定" name="postcard_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="postcard_image_format_quality_lp">
+ <slider label="画質" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
index 1502442a06..75bf28a3c8 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
@@ -29,30 +29,5 @@
<check_box label="IM チャット" name="EnableIMChatPopups" tool_tip="これを選択すると、インスタントメッセージを受信した際にポップアップが表示されます"/>
<spinner label="近くのチャットメッセージが表示される長さ:" name="nearby_toasts_lifetime"/>
<spinner label="近くのチャットメッセージが消えるまでの長さ:" name="nearby_toasts_fadingtime"/>
- <check_box label="Use machine translation while chatting" name="translate_chat_checkbox"/>
- <text name="translate_chb_label">
- チャット中に内容を機械翻訳する
- </text>
- <text name="translate_language_text">
- 翻訳する言語:
- </text>
- <combo_box name="translate_language_combobox">
- <combo_box.item label="システム標準" name="System Default Language"/>
- <combo_box.item label="English(英語)" name="English"/>
- <combo_box.item label="Dansk(デンマーク語)" name="Danish"/>
- <combo_box.item label="Deutsch(ドイツ語)" name="German"/>
- <combo_box.item label="Español(スペイン語)" name="Spanish"/>
- <combo_box.item label="Français(フランス語)" name="French"/>
- <combo_box.item label="Italiano(イタリア語)" name="Italian"/>
- <combo_box.item label="Magyar(ハンガリー語)" name="Hungarian"/>
- <combo_box.item label="Nederlands(オランダ語)" name="Dutch"/>
- <combo_box.item label="Polski(ポーランド語)" name="Polish"/>
- <combo_box.item label="Português(ポルトガル語)" name="Portugese"/>
- <combo_box.item label="Русский(ロシア語)" name="Russian"/>
- <combo_box.item label="Türkçe(トルコ語)" name="Turkish"/>
- <combo_box.item label="Українська(ウクライナ語)" name="Ukrainian"/>
- <combo_box.item label="中文 (正體) (Chinese)" name="Chinese"/>
- <combo_box.item label="日本語" name="Japanese"/>
- <combo_box.item label="한국어(韓国語)" name="Korean"/>
- </combo_box>
+ <button label="チャットの翻訳設定" name="ok_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
index 1bafa52fbe..91e1514e49 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
@@ -16,7 +16,7 @@
<combo_box.item label="Русский (ロシア語) - ベータ" name="Russian"/>
<combo_box.item label="Türkçe (トルコ語) - ベータ" name="Turkish"/>
<combo_box.item label="日本語 – ベータ" name="(Japanese)"/>
- <combo_box.item label="正體中文 (中国語 - 繁体字) - ベータ" name="Traditional Chinese"/>
+ <combo_box.item label="正體中文(簡体字中国語)- ベータ版" name="Traditional Chinese"/>
</combo_box>
<text name="language_textbox2">
(再起動後に反映)
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
index 7877c0495f..d90a1632ab 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
@@ -15,7 +15,7 @@
Web:
</text>
<radio_group name="use_external_browser">
- <radio_item label="指定のブラウザ(IE や Firefox)を使用" name="external" tool_tip="デフォルトのシステム Web ブラウザでヘルプや Web リンク先などを見ます。全画面で起動中にはおすすめしません。" value="1"/>
+ <radio_item label="指定のブラウザ(IE や Firefox)を使用" name="external" tool_tip="デフォルトのシステム Web ブラウザでヘルプや Web リンク先などを見ます。全画面で起動中にはおすすめしません。" value="true"/>
<radio_item label="内蔵ブラウザを使用" name="internal" tool_tip="内蔵ブラウザでヘルプや Web リンクなどを見ます。[APP_NAME] 内に新しいウィンドウでこのブラウザが開きます。" value=""/>
</radio_group>
<check_box initial_value="true" label="プラグインを有効にする" name="browser_plugins_enabled"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml
new file mode 100644
index 0000000000..46f2b0a3f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_inventory">
+ <text name="title">
+ 「持ち物」に保存
+ </text>
+ <text name="hint_lbl">
+ 画像を持ち物に保存するには L$[UPLOAD_COST] の費用がかかります。画像をテクスチャとして保存するには平方形式の 1 つを選択してください。
+ </text>
+ <combo_box label="解像度" name="texture_size_combo">
+ <combo_box.item label="現在のウィンドウ" name="CurrentWindow"/>
+ <combo_box.item label="小(128x128)" name="Small(128x128)"/>
+ <combo_box.item label="中(256x256)" name="Medium(256x256)"/>
+ <combo_box.item label="大(512x512)" name="Large(512x512)"/>
+ <combo_box.item label="カスタム" name="Custom"/>
+ </combo_box>
+ <spinner label="幅" name="inventory_snapshot_width"/>
+ <spinner label="高さ" name="inventory_snapshot_height"/>
+ <check_box label="縦横比の固定" name="inventory_keep_aspect_check"/>
+ <button label="取り消し" name="cancel_btn"/>
+ <button label="保存" name="save_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_local.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_local.xml
new file mode 100644
index 0000000000..cb658fb6c9
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_local.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_local">
+ <text name="title">
+ コンピューターに保存
+ </text>
+ <combo_box label="解像度" name="local_size_combo">
+ <combo_box.item label="現在のウィンドウ" name="CurrentWindow"/>
+ <combo_box.item label="320x240" name="320x240"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="1280x1024" name="1280x1024"/>
+ <combo_box.item label="1600x1200" name="1600x1200"/>
+ <combo_box.item label="カスタム" name="Custom"/>
+ </combo_box>
+ <layout_stack name="local_image_params_ls">
+ <layout_panel name="local_image_size_lp">
+ <spinner label="幅" name="local_snapshot_width"/>
+ <spinner label="高さ" name="local_snapshot_height"/>
+ <check_box label="縦横比の固定" name="local_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="local_image_format_quality_lp">
+ <combo_box label="書式" name="local_format_combo">
+ <combo_box.item label="PNG(可逆圧縮)" name="PNG"/>
+ <combo_box.item label="JPEG" name="JPEG"/>
+ <combo_box.item label="BMP(可逆圧縮)" name="BMP"/>
+ </combo_box>
+ <slider label="画質" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <button label="取り消し" name="cancel_btn"/>
+ <flyout_button label="保存" name="save_btn" tool_tip="画像をファイルに保存">
+ <flyout_button.item label="保存" name="save_item"/>
+ <flyout_button.item label="別名で保存..." name="saveas_item"/>
+ </flyout_button>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
new file mode 100644
index 0000000000..cd5b7590ad
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_options">
+ <button label="プロフィールフィードに投稿する" name="save_to_profile_btn"/>
+ <button label="メール" name="save_to_email_btn"/>
+ <button label="持ち物に保存(L$[Amount])" name="save_to_inventory_btn"/>
+ <button label="コンピューターに保存" name="save_to_computer_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml
new file mode 100644
index 0000000000..1ddd723840
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_postcard">
+ <string name="default_subject">
+ [SECOND_LIFE] からのポストカードです。
+ </string>
+ <string name="default_message">
+ ぜひご覧ください!
+ </string>
+ <string name="upload_message">
+ 送信中...
+ </string>
+ <text name="title">
+ メール
+ </text>
+ <button label="メッセージ" name="message_btn"/>
+ <button label="設定" name="settings_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_profile.xml
new file mode 100644
index 0000000000..b860a6afe9
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_profile.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_profile">
+ <text name="title">
+ プロフィールフィードに投稿する
+ </text>
+ <combo_box label="解像度" name="profile_size_combo">
+ <combo_box.item label="現在のウィンドウ" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="カスタム" name="Custom"/>
+ </combo_box>
+ <layout_stack name="profile_image_params_ls">
+ <layout_panel name="profile_image_size_lp">
+ <spinner label="幅" name="profile_snapshot_width"/>
+ <spinner label="高さ" name="profile_snapshot_height"/>
+ <check_box label="縦横比の固定" name="profile_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="profile_image_metadata_lp">
+ <text name="caption_label">
+ キャプション:
+ </text>
+ <check_box initial_value="true" label="場所を含む" name="add_location_cb"/>
+ </layout_panel>
+ </layout_stack>
+ <button label="取り消し" name="cancel_btn"/>
+ <button label="投稿" name="post_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_status_bar.xml b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
index 93689b81af..4fb876f690 100644
--- a/indra/newview/skins/default/xui/ja/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
@@ -18,7 +18,7 @@
<panel name="balance_bg">
<text name="balance" tool_tip="クリックして L$ 残高を更新" value="L$20"/>
<button label="L$ の購入" name="buyL" tool_tip="クリックして L$ を購入します"/>
- <button label="店" name="goShop" tool_tip="Second Life マーケットプレイスを開く"/>
+ <button label="店" name="goShop" tool_tip="Second Life マーケットプレイスを開く" width="40"/>
</panel>
<text name="TimeText" tool_tip="現在時刻(太平洋)">
24:00 AM PST
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index f611b96502..c6b033ed95 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -1214,7 +1214,7 @@ support@secondlife.com にお問い合わせください。
「持ち物」内にこのテクスチャのコピーがありません
</string>
<string name="InventoryInboxNoItems">
- マーケットプレイスで購入した商品はここに配達されます。
+ 購入するなどして取得したアイテムや商品はここに表示され、持ち物のフォルダにドラッグして移動することもできれば、要らなくなった場合には削除することができます。
</string>
<string name="MarketplaceURL">
http://marketplace.[DOMAIN_NAME]
@@ -1412,6 +1412,9 @@ support@secondlife.com にお問い合わせください。
<string name="no_attachments">
着用しているアタッチメントはありません
</string>
+ <string name="Attachments remain">
+ アタッチメント(残りのスロット数:[COUNT])
+ </string>
<string name="Buy">
買う
</string>
@@ -1538,6 +1541,12 @@ support@secondlife.com にお問い合わせください。
<string name="Right Pec">
右胸筋
</string>
+ <string name="Neck">
+ 首
+ </string>
+ <string name="Avatar Center">
+ アバターの中央
+ </string>
<string name="Invalid Attachment">
装着先が正しくありません
</string>
@@ -4030,6 +4039,18 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
<string name="you_paid_ldollars_no_name">
L$ [AMOUNT] を支払いました:[REASON]
</string>
+ <string name="you_paid_failure_ldollars">
+ [NAME] に [REASON] の代金 L$ [AMOUNT] を支払えませんでした。
+ </string>
+ <string name="you_paid_failure_ldollars_no_info">
+ L$ [AMOUNT] を支払えませんでした。
+ </string>
+ <string name="you_paid_failure_ldollars_no_reason">
+ [NAME] に L$ [AMOUNT] を支払えませんでした。
+ </string>
+ <string name="you_paid_failure_ldollars_no_name">
+ [REASON] の 代金 L$ [AMOUNT] を支払えませんでした。
+ </string>
<string name="for item">
[ITEM] 向け
</string>
@@ -4440,6 +4461,12 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
<string name="ExternalEditorFailedToRun">
外部エディターを実行できませんでした。
</string>
+ <string name="TranslationFailed">
+ 翻訳できませんでした:[REASON]
+ </string>
+ <string name="TranslationResponseParseError">
+ 翻訳の応答にエラーが発生しました。
+ </string>
<string name="Esc">
Esc
</string>
@@ -4810,7 +4837,7 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
ミニマップ
</string>
<string name="Command_Move_Label">
- 移動
+ 歩行 / 走行 / 飛行
</string>
<string name="Command_People_Label">
@@ -4837,10 +4864,10 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
話す
</string>
<string name="Command_View_Label">
- 視界
+ カメラコントロール
</string>
<string name="Command_Voice_Label">
- 近くのボイス
+ ボイス設定
</string>
<string name="Command_AboutLand_Tooltip">
訪問先に関する情報
@@ -4912,7 +4939,16 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
カメラの角度を変更
</string>
<string name="Command_Voice_Tooltip">
- ボイスチャット機能を持つ近くの人
+ インワールドでのコールや近くにいる人の音量調整
+ </string>
+ <string name="Toolbar_Bottom_Tooltip">
+ 現在、下のツールバーにあります
+ </string>
+ <string name="Toolbar_Left_Tooltip">
+ 現在、左のツールバーにあります
+ </string>
+ <string name="Toolbar_Right_Tooltip">
+ 現在、右のツールバーにあります
</string>
<string name="Retain%">
維持率
@@ -4938,4 +4974,19 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
<string name="Normal">
普通
</string>
+ <string name="snapshot_quality_very_low">
+ 非常に低い
+ </string>
+ <string name="snapshot_quality_low">
+ 低
+ </string>
+ <string name="snapshot_quality_medium">
+ 中
+ </string>
+ <string name="snapshot_quality_high">
+ 高
+ </string>
+ <string name="snapshot_quality_very_high">
+ 非常に高い
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/ja/teleport_strings.xml b/indra/newview/skins/default/xui/ja/teleport_strings.xml
index 04ea1c2438..6c69c7a231 100644
--- a/indra/newview/skins/default/xui/ja/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/ja/teleport_strings.xml
@@ -21,8 +21,8 @@
もう少し後でやり直してください。
</message>
<message name="NoHelpIslandTP">
- Welcome Islandには戻ることができません。
-「Welcome Island Public」に行き、
+ ウェルカムアイランドにテレポートで戻ることはできません。
+「Welcome Island Public」に行き再度チュートリアルを行ってください。
</message>
<message name="noaccess_tport">
残念ながら、そのテレポート目的地へのアクセスがありません。
diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml
index c072ea9b5a..24c961fa26 100644
--- a/indra/newview/skins/default/xui/pl/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml
@@ -20,8 +20,6 @@
<menu_item_call label="Tryb oddalenia" name="Set Away"/>
<menu_item_call label="Tryb pracy" name="Set Busy"/>
</menu>
- <menu_item_call label="Zażądaj statusu administratora" name="Request Admin Options"/>
- <menu_item_call label="Wyłącz atatus administratora" name="Leave Admin Options"/>
<menu_item_call label="Wyłącz [APP_NAME]" name="Quit"/>
</menu>
<menu label="Komunikacja" name="Communicate">
@@ -36,11 +34,10 @@
<menu_item_check label="Szukaj" name="Search"/>
<menu_item_call label="Zrób zdjęcie" name="Take Snapshot"/>
<menu_item_call label="Zapamiętaj to miejsce (LM)" name="Create Landmark Here"/>
- <menu label="Miejsce" name="Land">
- <menu_item_call label="Profil miejsca" name="Place Profile"/>
- <menu_item_call label="O posiadłości" name="About Land"/>
- <menu_item_call label="Region/Majątek" name="Region/Estate"/>
- </menu>
+ <menu_item_separator/>
+ <menu_item_call label="Profil miejsca" name="Place Profile"/>
+ <menu_item_call label="O posiadłości" name="About Land"/>
+ <menu_item_call label="Region/Majątek" name="Region/Estate"/>
<menu_item_call label="Kup posiadłość" name="Buy Land"/>
<menu_item_call label="Moje posiadłości" name="My Land"/>
<menu label="Pokaż" name="LandShow">
@@ -56,7 +53,7 @@
</menu>
<menu_item_call label="Teleportuj do Miejsca Startu" name="Teleport Home"/>
<menu_item_call label="Ustaw Miejsce Startu" name="Set Home to Here"/>
- <menu label="Słońce" name="Environment Settings">
+ <menu label="Słońce" name="Sun">
<menu_item_call label="Wschód Słońca" name="Sunrise"/>
<menu_item_call label="Południe" name="Noon"/>
<menu_item_call label="Zachód Słońca" name="Sunset"/>
@@ -153,22 +150,22 @@
<menu_item_check label="Pokaż celownik myszki" name="ShowCrosshairs"/>
</menu>
<menu label="Rodzaje renderowania" name="Rendering Types">
- <menu_item_check label="Podstawowe" name="Simple"/>
- <menu_item_check label="Maska alpha" name="Alpha"/>
- <menu_item_check label="Drzewo" name="Tree"/>
- <menu_item_check label="Awatary" name="Character"/>
- <menu_item_check label="Płaszczyzna powierzchni" name="SurfacePath"/>
- <menu_item_check label="Niebo" name="Sky"/>
- <menu_item_check label="Woda" name="Water"/>
- <menu_item_check label="Ziemia" name="Ground"/>
- <menu_item_check label="Głośność" name="Volume"/>
- <menu_item_check label="Trawa" name="Grass"/>
- <menu_item_check label="Chmury" name="Clouds"/>
- <menu_item_check label="Cząsteczki" name="Particles"/>
- <menu_item_check label="Zderzenie" name="Bump"/>
+ <menu_item_check label="Podstawowe" name="Rendering Type Simple"/>
+ <menu_item_check label="Maska alpha" name="Rendering Type Alpha"/>
+ <menu_item_check label="Drzewo" name="Rendering Type Tree"/>
+ <menu_item_check label="Awatary" name="Rendering Type Character"/>
+ <menu_item_check label="Płaszczyzna powierzchni" name="Rendering Type Surface Patch"/>
+ <menu_item_check label="Niebo" name="Rendering Type Sky"/>
+ <menu_item_check label="Woda" name="Rendering Type Water"/>
+ <menu_item_check label="Ziemia" name="Rendering Type Ground"/>
+ <menu_item_check label="Głośność" name="Rendering Type Volume"/>
+ <menu_item_check label="Trawa" name="Rendering Type Grass"/>
+ <menu_item_check label="Chmury" name="Rendering Type Clouds"/>
+ <menu_item_check label="Cząsteczki" name="Rendering Type Particles"/>
+ <menu_item_check label="Zderzenie" name="Rendering Type Bump"/>
</menu>
<menu label="Opcje renderowania" name="Rendering Features">
- <menu_item_check label="UI" name="UI"/>
+ <menu_item_check label="UI" name="ToggleUI"/>
<menu_item_check label="Zaznaczone" name="Selected"/>
<menu_item_check label="Podświetlenie" name="Highlighted"/>
<menu_item_check label="Tekstury dynamiczne" name="Dynamic Textures"/>
@@ -180,10 +177,7 @@
<menu_item_call label="Wyczyść bufor danych grupy" name="ClearGroupCache"/>
<menu_item_check label="Wygładzanie ruchu myszki" name="Mouse Smoothing"/>
<menu label="Skróty" name="Shortcuts">
- <menu_item_call label="Obraz (L$[COST])..." name="Upload Image"/>
- <menu_item_check label="Szukaj" name="Search"/>
<menu_item_call label="Zwolnij klawisze" name="Release Keys"/>
- <menu_item_call label="Domyślne ustawienia rozmiaru interfejsu" name="Set UI Size to Default"/>
<menu_item_check label="Pokaż menu Zaawansowane - skrót" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="Zamknij okno" name="Close Window"/>
<menu_item_call label="Zamknij wszystkie okna" name="Close All Windows"/>
@@ -192,13 +186,6 @@
<menu_item_check label="Wolna kamera" name="Joystick Flycam"/>
<menu_item_call label="Reset widoku" name="Reset View"/>
<menu_item_call label="Zobacz ostatniego rozmówcę" name="Look at Last Chatter"/>
- <menu label="Wybierz narzędzie budowania" name="Select Tool">
- <menu_item_call label="Narzędzie ogniskowej" name="Focus"/>
- <menu_item_call label="Narzędzie ruchu" name="Move"/>
- <menu_item_call label="Narzędzie edycji" name="Edit"/>
- <menu_item_call label="Stwórz narzędzie" name="Create"/>
- <menu_item_call label="Narzędzia posiadłości" name="Land"/>
- </menu>
<menu_item_call label="Przybliż" name="Zoom In"/>
<menu_item_call label="Domyślne przybliżenie" name="Zoom Default"/>
<menu_item_call label="Oddal" name="Zoom Out"/>
@@ -267,9 +254,8 @@
<menu_item_call label="Upuść pakiet pamięci" name="Drop a Packet"/>
</menu>
<menu_item_call label="Zderzenia, popchnięcia &amp; uderzenia" name="Bumps, Pushes &amp;amp; Hits"/>
- <menu label="Świat" name="World">
+ <menu label="Świat" name="DevelopWorld">
<menu_item_check label="Domyślne ustawienia środowiska Regionu" name="Sim Sun Override"/>
- <menu_item_check label="Efekty emiterów" name="Cheesy Beacon"/>
<menu_item_check label="Ustalona pogoda" name="Fixed Weather"/>
<menu_item_call label="Zachowaj bufor pamięci obiektów regionu" name="Dump Region Object Cache"/>
</menu>
@@ -291,11 +277,11 @@
</menu>
<menu label="Awatar" name="Character">
<menu label="Przesuń bakowaną teksturę" name="Grab Baked Texture">
- <menu_item_call label="Tęczówka oka" name="Iris"/>
- <menu_item_call label="Głowa" name="Head"/>
- <menu_item_call label="Górna część ciała" name="Upper Body"/>
- <menu_item_call label="Dolna część ciała" name="Lower Body"/>
- <menu_item_call label="Spódnica" name="Skirt"/>
+ <menu_item_call label="Tęczówka oka" name="Grab Iris"/>
+ <menu_item_call label="Głowa" name="Grab Head"/>
+ <menu_item_call label="Górna część ciała" name="Grab Upper Body"/>
+ <menu_item_call label="Dolna część ciała" name="Grab Lower Body"/>
+ <menu_item_call label="Spódnica" name="Grab Skirt"/>
</menu>
<menu label="Testy postaci" name="Character Tests">
<menu_item_call label="Przesuń geometrię postaci" name="Toggle Character Geometry"/>
@@ -316,8 +302,8 @@
<menu_item_check label="Pokaż menu administratora" name="View Admin Options"/>
</menu>
<menu label="Administrator" name="Admin">
- <menu label="Object">
- <menu_item_call label="Weź kopię" name="Take Copy"/>
+ <menu label="Object" name="AdminObject">
+ <menu_item_call label="Weź kopię" name="Admin Take Copy"/>
<menu_item_call label="Reset właściciela" name="Force Owner To Me"/>
<menu_item_call label="Reset przyzwolenia właściciela" name="Force Owner Permissive"/>
<menu_item_call label="Usuń" name="Delete"/>
diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml
index e1fb6dd3f1..0194293642 100644
--- a/indra/newview/skins/default/xui/pl/notifications.xml
+++ b/indra/newview/skins/default/xui/pl/notifications.xml
@@ -1385,7 +1385,7 @@ W celu instalacji aktualizacji musi zostać wykonany restart [APP_NAME].
<usetemplate ignoretext="Potwierdź zanim zwrócisz obiekty do ich właścicieli" name="okcancelignore" notext="Anuluj" yestext="OK"/>
</notification>
<notification name="GroupLeaveConfirmMember">
- Jesteś członkiem grupy [GROUP].
+ Jesteś członkiem grupy &lt;nolink&gt;[GROUP]&lt;/nolink&gt;.
Chcesz opuścić grupę?
<usetemplate name="okcancelbuttons" notext="Anuluj" yestext="OK"/>
</notification>
diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml
index c374264c4a..e843e56090 100644
--- a/indra/newview/skins/default/xui/pt/floater_about.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about.xml
@@ -65,13 +65,35 @@ Versão do servidor de voz: [VOICE_VERSION]
</panel>
<panel label="Licenças" name="licenses_panel">
<text_editor name="credits_editor">
- 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion APR Copyright (C) 2000-2004 The Apache Software Foundation Collada DOM Copyright 2005 Sony Computer Entertainment Inc. cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). GL Copyright (C) 1999-2004 Brian Paul. GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) jpeglib Copyright (C) 1991-1998, Thomas G. Lane. ogg/vorbis Copyright (C) 2001, Xiphophorus OpenSSL Copyright (C) 1998-2002 The OpenSSL Project. PCRE Copyright (c) 1997-2008 University of Cambridge SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. google-perftools Copyright (c) 2005, Google Inc.
+ 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
+ APR Copyright (C) 2000-2004 The Apache Software Foundation
+ Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
+ expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+ FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ GL Copyright (C) 1999-2004 Brian Paul.
+ GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University e David Luebke, Brenden Schubert, University of Virginia.
+ google-perftools Copyright (c) 2005, Google Inc.
+ Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
+ jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
+ jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
+ ogg/vorbis Copyright (C) 2001, Xiphophorus
+ OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2008 University of Cambridge
+ SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+ SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
+ zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
+ google-perftools Copyright (c) 2005, Google Inc.
-O Second Life Viewer usa Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e licenciadores). Todos os direitos reservados. Mais detalhes em www.havok.com
+ O Visualizador do Second Life usa Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e seus Licenciantes). Todos os direitos reservados. Consulte www.havok.com para obter detalhes.
-Todos os direitos reservados. Mais detalhes em licenses.txt.
+ Este software contém código fonte fornecido pela NVIDIA Corporation.
-Codificação do áudio de bate-papo de voz: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
+ Todos os direitos reservados. Consulte licenses.txt para obter detalhes.
+
+ Codificação de áudio da conversa com voz: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
</text_editor>
</panel>
</tab_container>
diff --git a/indra/newview/skins/default/xui/pt/floater_about_land.xml b/indra/newview/skins/default/xui/pt/floater_about_land.xml
index cc09888994..30d4b0290c 100644
--- a/indra/newview/skins/default/xui/pt/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about_land.xml
@@ -130,7 +130,7 @@ Vá para o menu Mundo &gt; Sobre o terreno ou selecione outro lote para mostrar
Tráfego:
</text>
<text name="DwellText">
- 0
+ Carregando...
</text>
<button label="Comprar terreno..." label_selected="Comprar terreno..." left="130" name="Buy Land..." width="125"/>
<button label="Venda Linden" name="Linden Sale..." tool_tip="O terreno precisa ser possuído, estar com o conteúdo configurado e não estar pronto para leilão."/>
@@ -309,13 +309,15 @@ Apenas lotes maiores podem ser listados na busca.
Proibido empurrar (regulamento da região)
</panel.string>
<panel.string name="see_avs_text">
- Veja e bata papo com os residentes deste terreno
+ Avatares em outros lotes podem ver
</panel.string>
<text name="allow_label">
Autorizar outros residentes a:
</text>
- <check_box label="Editar terreno" name="edit land check" tool_tip="Se ativado, qualquer um pode modificar o terreno. É melhor deixar esta opção desativada, uma vez que você sempre pode editar seu próprio terreno."/>
- <check_box label="Voar" name="check fly" tool_tip="Se ativado, residentes podem voar sobre seu terreno. Se desativado, eles podem voar apenas até chegar ou sobrevoar o seu terreno."/>
+ <text name="allow_label0">
+ Voar:
+ </text>
+ <check_box label="Todos" name="check fly" tool_tip="Se ativado, residentes podem voar sobre seu terreno. Se desativado, eles podem voar apenas até chegar ou sobrevoar o seu terreno."/>
<text name="allow_label2">
Criar objetos:
</text>
@@ -331,9 +333,6 @@ Apenas lotes maiores podem ser listados na busca.
</text>
<check_box label="Residentes" name="check other scripts"/>
<check_box label="Grupo" name="check group scripts"/>
- <text name="land_options_label">
- Opções do terreno:
- </text>
<check_box label="Seguro (sem danos)" name="check safe" tool_tip="Se ativado, ajusta o terreno para Seguro, impedindo lutas com danos. Se não ativado, lutas com danos é habilitado."/>
<check_box label="Proibido empurrar" name="PushRestrictCheck" tool_tip="Evita scripts que empurram. Ativar essa opção ajuda a prevenir comportamentos desordeiros no seu terreno."/>
<check_box label="Mostrar terreno nos resultados de busca (L$30/semana)" name="ShowDirectoryCheck" tool_tip="Permitir que as pessoas vejam este terreno nos resultados de busca"/>
@@ -374,9 +373,9 @@ Apenas lotes maiores podem ser listados na busca.
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Clique para escolher uma imagem"/>
<text name="allow_label5">
- Permitir que residentes de outros terrenos:
+ e bater papo com avatares neste lote
</text>
- <check_box label="Ver avatares" name="SeeAvatarsCheck" tool_tip="Permite que residentes de outros terrenos vejam e conversem com os residentes deste terreno e vice-versa."/>
+ <check_box label="Ver avatares" name="SeeAvatarsCheck" tool_tip="Permite que os avatares em outros lotes vejam e batam papo com avatares neste lote. Você poderá vê-los e conversar com eles."/>
<text name="landing_point">
Ponto de Aterrissagem: [LANDING]
</text>
diff --git a/indra/newview/skins/default/xui/pt/floater_avatar.xml b/indra/newview/skins/default/xui/pt/floater_avatar.xml
index f51b765105..168cdacae1 100644
--- a/indra/newview/skins/default/xui/pt/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/pt/floater_avatar.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Avatar" title="SELETOR DE AVATAR"/>
+<floater name="Avatar" title="ESCOLHA UM AVATAR"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_buy_currency.xml b/indra/newview/skins/default/xui/pt/floater_buy_currency.xml
index b5ba477fe5..2845a29e1d 100644
--- a/indra/newview/skins/default/xui/pt/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/pt/floater_buy_currency.xml
@@ -46,7 +46,7 @@
L$ [AMT]
</text>
<text name="currency_links">
- [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
+ [http://www.secondlife.com/my/account/payment_method_management.php método de pagamento] | [http://www.secondlife.com/my/account/currency.php moeda]
</text>
<text name="exchange_rate_note">
Digite o valor novamente para ver o câmbio atual.
diff --git a/indra/newview/skins/default/xui/pt/floater_camera.xml b/indra/newview/skins/default/xui/pt/floater_camera.xml
index 6b66d01781..9cda01c187 100644
--- a/indra/newview/skins/default/xui/pt/floater_camera.xml
+++ b/indra/newview/skins/default/xui/pt/floater_camera.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="camera_floater" title="EXIBIR">
+<floater name="camera_floater" title="CONTROLES DA CÂMERA">
<floater.string name="rotate_tooltip">
Girar a Câmera ao redor do Foco
</floater.string>
diff --git a/indra/newview/skins/default/xui/pt/floater_chat_bar.xml b/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
index c089ab93f2..72016c6b40 100644
--- a/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="chat_bar" title="BATE-PAPO LOCAL">
- <panel>
+ <panel name="bottom_panel">
<line_editor label="Clique aqui para bater papo." name="chat_box" tool_tip="Tecle Enter para falar, Ctrl+Enter para gritar"/>
<button name="show_nearby_chat" tool_tip="Mostra/oculta o histórico do bate-papo local"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml b/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
index 8c95a3b548..1bc2bce768 100644
--- a/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
@@ -4,7 +4,7 @@
Filtragem:
</text>
<check_box label="Filtragem Anisotrópica (mais lento quando habilitada)" name="ani"/>
- <text name="Antialiasing:">
+ <text name="antialiasing label">
Suavização:
</text>
<combo_box label="Suavização" name="fsaa" width="94">
diff --git a/indra/newview/skins/default/xui/pt/floater_model_preview.xml b/indra/newview/skins/default/xui/pt/floater_model_preview.xml
index 17abe72173..8960500831 100644
--- a/indra/newview/skins/default/xui/pt/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_model_preview.xml
@@ -4,6 +4,9 @@
<string name="status_parse_error">
Erro: Problema ao analisar .dae - consulte log para obter detalhes.
</string>
+ <string name="status_material_mismatch">
+ Erro: o material do modelo não é um subconjunto do modelo de referência.
+ </string>
<string name="status_reading_file">
Carregando...
</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_model_wizard.xml b/indra/newview/skins/default/xui/pt/floater_model_wizard.xml
index d9195adbf9..498058f933 100644
--- a/indra/newview/skins/default/xui/pt/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/pt/floater_model_wizard.xml
@@ -20,6 +20,9 @@
Escolha o arquivo de modelo para upload
</text>
<button label="Procurar..." label_selected="Procurar..." name="browse"/>
+ <text name="Model types">
+ O Second Life oferece suporte a arquivos COLLADA (.dae)
+ </text>
<text name="dimensions">
X Y Z
</text>
diff --git a/indra/newview/skins/default/xui/pt/floater_moveview.xml b/indra/newview/skins/default/xui/pt/floater_moveview.xml
index 0cb6f9a98e..728357a400 100644
--- a/indra/newview/skins/default/xui/pt/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_moveview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="move_floater" title="MOVER">
+<floater name="move_floater" title="ANDAR/CORRER/VOAR">
<string name="walk_forward_tooltip">
Andar para frente (flecha para cima ou W)
</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_snapshot.xml b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
index d62fe3dd20..4110e69068 100644
--- a/indra/newview/skins/default/xui/pt/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
@@ -3,73 +3,63 @@
<floater.string name="unknown">
desconhecido
</floater.string>
- <radio_group label="Tipo de foto" name="snapshot_type_radio">
- <radio_item label="Email" name="postcard"/>
- <radio_item label="Meu inventário (L$[AMOUNT])" name="texture"/>
- <radio_item label="Salvar no meu PC" name="local"/>
- </radio_group>
+ <string name="postcard_progress_str">
+ Enviando e-mail
+ </string>
+ <string name="profile_progress_str">
+ Postando
+ </string>
+ <string name="inventory_progress_str">
+ Salvando no inventário
+ </string>
+ <string name="local_progress_str">
+ Salvo no computador
+ </string>
+ <string name="profile_succeeded_str">
+ Imagem carregada
+ </string>
+ <string name="postcard_succeeded_str">
+ E-mail enviado!
+ </string>
+ <string name="inventory_succeeded_str">
+ Salvo no inventário!
+ </string>
+ <string name="local_succeeded_str">
+ Salvo no computador!
+ </string>
+ <string name="profile_failed_str">
+ Falha ao carregar a imagem no feed do seu perfil.
+ </string>
+ <string name="postcard_failed_str">
+ Falha ao enviar e-mail.
+ </string>
+ <string name="inventory_failed_str">
+ Falha ao salvar no inventário.
+ </string>
+ <string name="local_failed_str">
+ Falha ao salvar no computador.
+ </string>
+ <button name="advanced_options_btn" tool_tip="Opções avançadas"/>
+ <text name="image_res_text">
+ [WIDTH] x [HEIGHT] px
+ </text>
<text name="file_size_label">
[TAMANHO] KB
</text>
- <button label="Atualizar a foto" name="new_snapshot_btn"/>
- <button label="Enviar" name="send_btn"/>
- <button label="Economize (L$[AMOUNT])" name="upload_btn"/>
- <flyout_button label="Salvar" name="save_btn" tool_tip="Salvar imagem em um arquivo">
- <flyout_button.item label="Salvar" name="save_item"/>
- <flyout_button.item label="Salvar como..." name="saveas_item"/>
- </flyout_button>
- <button label="Mais" name="more_btn" tool_tip="Opções avançadas"/>
- <button label="Menos" name="less_btn" tool_tip="Opções avançadas"/>
- <button label="Cancelar" name="discard_btn"/>
- <text name="type_label2">
- Tamanho
- </text>
- <text name="format_label">
- Formato
- </text>
- <combo_box label="Resolução" name="postcard_size_combo">
- <combo_box.item label="Janela atual" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="Customizado" name="Custom"/>
- </combo_box>
- <combo_box label="Resolução" name="texture_size_combo">
- <combo_box.item label="Janela atual" name="CurrentWindow"/>
- <combo_box.item label="Pequeno (128x128)" name="Small(128x128)"/>
- <combo_box.item label="Médio (256x256)" name="Medium(256x256)"/>
- <combo_box.item label="Grande (512x512)" name="Large(512x512)"/>
- <combo_box.item label="Customizado" name="Custom"/>
- </combo_box>
- <combo_box label="Resolução" name="local_size_combo">
- <combo_box.item label="Janela atual" name="CurrentWindow"/>
- <combo_box.item label="320x240" name="320x240"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1280x1024" name="1280x1024"/>
- <combo_box.item label="1600x1200" name="1600x1200"/>
- <combo_box.item label="Customizado" name="Custom"/>
- </combo_box>
- <combo_box label="Formato" name="local_format_combo">
- <combo_box.item label="PNG" name="PNG"/>
- <combo_box.item label="JPEG" name="JPEG"/>
- <combo_box.item label="BMP" name="BMP"/>
- </combo_box>
- <spinner label="Largura" name="snapshot_width"/>
- <spinner label="Altura" name="snapshot_height"/>
- <check_box label="Limitar proproções" name="keep_aspect_check"/>
- <slider label="Qualidade da imagem" name="image_quality_slider"/>
- <text name="layer_type_label">
- Capturar:
- </text>
- <combo_box label="Camadas da imagem" name="layer_types">
- <combo_box.item label="Cores" name="Colors"/>
- <combo_box.item label="Profundidade" name="Depth"/>
- </combo_box>
- <check_box label="Interface" name="ui_check"/>
- <check_box label="HUDs" name="hud_check"/>
- <check_box label="Deixar aberto depois de salvo" name="keep_open_check"/>
- <check_box label="Gerar quadro (tela inteira)" name="freeze_frame_check"/>
- <check_box label="Atualizar" name="auto_snapshot_check"/>
+ <panel name="advanced_options_panel">
+ <text name="advanced_options_label">
+ OPÇÕES AVANÇADAS
+ </text>
+ <text name="layer_type_label">
+ Capturar:
+ </text>
+ <combo_box label="Camadas da imagem" name="layer_types">
+ <combo_box.item label="Cores" name="Colors"/>
+ <combo_box.item label="Profundidade" name="Depth"/>
+ </combo_box>
+ <check_box label="Interface" name="ui_check"/>
+ <check_box label="HUDs" name="hud_check"/>
+ <check_box label="Gerar quadro (tela inteira)" name="freeze_frame_check"/>
+ <check_box label="Atualização automática" name="auto_snapshot_check"/>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_toybox.xml b/indra/newview/skins/default/xui/pt/floater_toybox.xml
index 67076beb0f..3677c3b1f5 100644
--- a/indra/newview/skins/default/xui/pt/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/pt/floater_toybox.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Toybox" title="PERSONALIZAR BARRAS DE FERRAMENTA">
+<floater name="Toybox" title="BOTÕES DA BARRA DE FERRAMENTAS">
<text name="toybox label 1">
Adicione ou remova botões arrastando-os para dentro ou para fora das barras de ferramentas.
</text>
<text name="toybox label 2">
Os botões aparecerão como mostrado ou somente como ícone, dependendo das configurações de cada barra de ferramentas.
</text>
+ <button label="Limpar todas as barras de ferramentas" label_selected="Limpar todas as barras de ferramentas" name="btn_clear_all"/>
<button label="Restaurar padrão" label_selected="Restaurar padrão" name="btn_restore_defaults"/>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_translation_settings.xml b/indra/newview/skins/default/xui/pt/floater_translation_settings.xml
new file mode 100644
index 0000000000..1955599a81
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_translation_settings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_translation_settings" title="CONFIGURAÇÕES DE TRADUÇÃO DE BATE-PAPO">
+ <string name="bing_api_key_not_verified">
+ appID do Bing não verificada. Tente novamente.
+ </string>
+ <string name="google_api_key_not_verified">
+ Chave do API do Google não verificada. Tente novamente.
+ </string>
+ <string name="bing_api_key_verified">
+ appID do Bing verificada.
+ </string>
+ <string name="google_api_key_verified">
+ Chave do API do Google verificada.
+ </string>
+ <check_box label="Permitir a tradução de máquina durante o bate-papo" name="translate_chat_checkbox"/>
+ <text name="translate_language_label">
+ Traduzir bate-papo para:
+ </text>
+ <combo_box name="translate_language_combo">
+ <combo_box.item label="Padrão" name="System Default Language"/>
+ <combo_box.item label="Inglês" name="English"/>
+ <combo_box.item label="Dansk (Dinamarquês)" name="Danish"/>
+ <combo_box.item label="Deutsch (Alemão)" name="German"/>
+ <combo_box.item label="Español (Espanhol)" name="Spanish"/>
+ <combo_box.item label="Français (Francês)" name="French"/>
+ <combo_box.item label="Italiano (Italiano)" name="Italian"/>
+ <combo_box.item label="Magyar (Húngaro)" name="Hungarian"/>
+ <combo_box.item label="Nederlands (Holandês)" name="Dutch"/>
+ <combo_box.item label="Polski (Polonês)" name="Polish"/>
+ <combo_box.item label="Português (Português)" name="Portugese"/>
+ <combo_box.item label="Русский (Russo)" name="Russian"/>
+ <combo_box.item label="Türkçe (Turco)" name="Turkish"/>
+ <combo_box.item label="Українська (Ucraniano)" name="Ukrainian"/>
+ <combo_box.item label="中文 (简体) (Chinês)" name="Chinese"/>
+ <combo_box.item label="日本語 (Japonês)" name="Japanese"/>
+ <combo_box.item label="한국어 (Coreano)" name="Korean"/>
+ </combo_box>
+ <text name="tip">
+ Escolha o serviço de tradução:
+ </text>
+ <radio_group name="translation_service_rg">
+ <radio_item initial_value="bing" label="Bing Translator" name="bing"/>
+ <radio_item initial_value="google" label="Google Translate" name="google"/>
+ </radio_group>
+ <text name="bing_api_key_label">
+ [http://www.bing.com/developers/createapp.aspx AppID] do Bing:
+ </text>
+ <button label="Verificar" name="verify_bing_api_key_btn"/>
+ <text name="google_api_key_label">
+ [http://code.google.com/apis/language/translate/v2/getting_started.html#auth Chave API] do Google:
+ </text>
+ <button label="Verificar" name="verify_google_api_key_btn"/>
+ <text name="google_links_text">
+ [http://code.google.com/apis/language/translate/v2/pricing.html Preços] | [https://code.google.com/apis/console Estatísticas]
+ </text>
+ <button label="OK" name="ok_btn"/>
+ <button label="Cancelar" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_voice_controls.xml b/indra/newview/skins/default/xui/pt/floater_voice_controls.xml
index 6132479041..745a7d0e00 100644
--- a/indra/newview/skins/default/xui/pt/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/pt/floater_voice_controls.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_voice_controls" title="CONTROLES DE VOZ">
<string name="title_nearby">
- Voz próxima
+ CONFIGURAÇÕES DE VOZ
</string>
<string name="title_group">
- Ligação de grupo com [GROUP]
+ LIGAÇÃO DE GRUPO COM [GROUP]
</string>
<string name="title_adhoc">
- Teleconferência
+ TELECONFERÊNCIA
</string>
<string name="title_peer_2_peer">
- Ligação para [NAME]
+ LIGAÇÃO PARA [NAME]
</string>
<string name="no_one_near">
Ninguém por perto ativou a voz
diff --git a/indra/newview/skins/default/xui/pt/menu_toolbars.xml b/indra/newview/skins/default/xui/pt/menu_toolbars.xml
index f1e41aaea9..b58a1a6e4f 100644
--- a/indra/newview/skins/default/xui/pt/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/pt/menu_toolbars.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Toolbars Popup">
- <menu_item_call label="Escolher botões..." name="Chose Buttons"/>
+ <menu_item_call label="Remover este botão" name="Remove button"/>
+ <menu_item_call label="Botões da barra de ferramentas..." name="Choose Buttons"/>
<menu_item_check label="Ícones e rótulos" name="icons_with_text"/>
<menu_item_check label="Somente ícones" name="icons_only"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml
index 5ff2d49ac1..119a3bdcfe 100644
--- a/indra/newview/skins/default/xui/pt/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu_bar name="Main Menu">
<menu label="Eu" name="Me">
- <menu_item_call label="Painel..." name="Manage My Account">
- <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=pt"/>
- </menu_item_call>
<menu_item_call label="Perfil..." name="Profile"/>
<menu_item_call label="Aparência..." name="ChangeOutfit"/>
+ <menu_item_call label="Selecione um avatar..." name="Avatar Picker"/>
<menu_item_check label="Inventário..." name="Inventory"/>
- <menu_item_check label="Gestos..." name="Gestures"/>
- <menu_item_check label="Voz..." name="ShowVoice"/>
+ <menu_item_call label="Nova janela de inventário" name="NewInventoryWindow"/>
+ <menu_item_call label="Lugares..." name="Places"/>
+ <menu_item_call label="Destaques..." name="Picks"/>
+ <menu_item_call label="Controles da câmera..." name="Camera Controls"/>
<menu label="Movimentos" name="Movement">
<menu_item_call label="Sentar" name="Sit Down Here"/>
<menu_item_check label="Voar" name="Fly"/>
@@ -22,34 +22,39 @@
<menu_item_call label="Request Admin Status" name="Request Admin Options"/>
<menu_item_call label="Sair do modo admin" name="Leave Admin Options"/>
<menu_item_call label="Comprar L$" name="Buy and Sell L$"/>
+ <menu_item_call label="Painel da conta..." name="Manage My Account">
+ <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=pt"/>
+ </menu_item_call>
<menu_item_call label="Preferências..." name="Preferences"/>
- <menu_item_call label="Barras de ferramentas..." name="Toolbars"/>
+ <menu_item_call label="Botões da barra de ferramentas..." name="Toolbars"/>
<menu_item_call label="Ocultar todos os controles" name="Hide UI"/>
<menu_item_call label="Sair do [APP_NAME]" name="Quit"/>
</menu>
<menu label="Comunicar" name="Communicate">
- <menu_item_call label="Meus amigos" name="My Friends"/>
- <menu_item_call label="Meus grupos" name="My Groups"/>
- <menu_item_check label="Bate-papo local" name="Nearby Chat"/>
- <menu_item_call label="Pessoas por perto" name="Active Speakers"/>
- <menu_item_check label="Voz por perto" name="Nearby Voice"/>
+ <menu_item_check label="Bate-papo..." name="Nearby Chat"/>
+ <menu_item_check label="Falar" name="Speak"/>
+ <menu_item_check label="Configurações de voz..." name="Nearby Voice"/>
+ <menu_item_check label="Distorção de voz..." name="ShowVoice"/>
+ <menu_item_check label="Gestos..." name="Gestures"/>
+ <menu_item_call label="Amigos" name="My Friends"/>
+ <menu_item_call label="Grupos" name="My Groups"/>
+ <menu_item_call label="Pessoas próximas" name="Active Speakers"/>
</menu>
<menu label="Mundo" name="World">
- <menu_item_check label="Mini Mapa" name="Mini-Map"/>
+ <menu_item_call label="Criar marco deste lugar" name="Create Landmark Here"/>
+ <menu_item_call label="Destinos..." name="Destinations"/>
<menu_item_check label="Mapa-múndi" name="World Map"/>
+ <menu_item_check label="Mini Mapa" name="Mini-Map"/>
<menu_item_check label="Busca" name="Search"/>
+ <menu_item_call label="Teletransportar para início" name="Teleport Home"/>
+ <menu_item_call label="Definir como casa" name="Set Home to Here"/>
<menu_item_call label="Foto" name="Take Snapshot"/>
- <menu_item_call label="Criar marco deste lugar" name="Create Landmark Here"/>
- <menu label="Perfil da região" name="Land">
- <menu_item_call label="Perfil da região" name="Place Profile"/>
- <menu_item_call label="Sobre terrenos" name="About Land"/>
- <menu_item_call label="Região/Propriedade" name="Region/Estate"/>
- </menu>
+ <menu_item_call label="Perfil da região" name="Place Profile"/>
+ <menu_item_call label="Sobre terrenos" name="About Land"/>
+ <menu_item_call label="Região/Propriedade" name="Region/Estate"/>
+ <menu_item_call label="Meus terrenos..." name="My Land"/>
<menu_item_call label="Comprar este terreno" name="Buy Land"/>
- <menu_item_call label="Meus terrenos" name="My Land"/>
<menu label="Mostrar" name="LandShow">
- <menu_item_check label="Controles de movimento" name="Movement Controls"/>
- <menu_item_check label="Ver controles" name="Camera Controls"/>
<menu_item_check label="Limites" name="Ban Lines"/>
<menu_item_check label="Balizas" name="beacons"/>
<menu_item_check label="Limites do imóvel" name="Property Lines"/>
@@ -58,30 +63,29 @@
<menu_item_check label="Propriedades do lote" name="Parcel Properties"/>
<menu_item_check label="Menu avançado" name="Show Advanced Menu"/>
</menu>
- <menu_item_call label="Teletransportar para meu início" name="Teleport Home"/>
- <menu_item_call label="Definir como Início" name="Set Home to Here"/>
<menu label="Sol" name="Environment Settings">
<menu_item_call label="Amanhecer" name="Sunrise"/>
<menu_item_call label="Meio-dia" name="Noon"/>
<menu_item_call label="Pôr-do-Sol" name="Sunset"/>
<menu_item_call label="Meia-noite" name="Midnight"/>
- </menu>
- <menu label="Editor de ambientes" name="Enviroment Editor">
- <menu_item_call label="Configurações de ambiente..." name="Enviroment Settings"/>
- <menu label="Pré-configurações de água" name="Water Presets">
- <menu_item_call label="Nova pré-configuração..." name="new_water_preset"/>
- <menu_item_call label="Editar pré-configuração..." name="edit_water_preset"/>
- <menu_item_call label="Excluir pré-configuração..." name="delete_water_preset"/>
+ <menu_item_call label="Usar configurações da região" name="Use Region Settings"/>
+ </menu>
+ <menu label="Editor de ambientes" name="Environment Editor">
+ <menu_item_call label="Configurações do ambiente..." name="Environment Settings"/>
+ <menu label="Predefinições da água" name="Water Presets">
+ <menu_item_call label="Nova predefinição..." name="new_water_preset"/>
+ <menu_item_call label="Editar predefinição..." name="edit_water_preset"/>
+ <menu_item_call label="Excluir predefinição..." name="delete_water_preset"/>
</menu>
- <menu label="Pré-configurações de céu" name="Sky Presets">
- <menu_item_call label="Nova pré-configuração..." name="new_sky_preset"/>
- <menu_item_call label="Editar pré-configuração..." name="edit_sky_preset"/>
- <menu_item_call label="Excluir pré-configuração..." name="delete_sky_preset"/>
+ <menu label="Predefinições de céu" name="Sky Presets">
+ <menu_item_call label="Nova predefinição..." name="new_sky_preset"/>
+ <menu_item_call label="Editar predefinição..." name="edit_sky_preset"/>
+ <menu_item_call label="Excluir predefinição..." name="delete_sky_preset"/>
</menu>
- <menu label="Pré-configurações de dias" name="Day Presets">
- <menu_item_call label="Nova pré-configuração..." name="new_day_preset"/>
- <menu_item_call label="Editar pré-configuração..." name="edit_day_preset"/>
- <menu_item_call label="Excluir pré-configuração..." name="delete_day_preset"/>
+ <menu label="Predefinições do dia" name="Day Presets">
+ <menu_item_call label="Nova predefinição..." name="new_day_preset"/>
+ <menu_item_call label="Editar predefinição..." name="edit_day_preset"/>
+ <menu_item_call label="Excluir predefinição..." name="delete_day_preset"/>
</menu>
</menu>
</menu>
@@ -146,6 +150,7 @@
<menu_item_call label="Repetir" name="Redo"/>
</menu>
<menu label="Ajuda" name="Help">
+ <menu_item_call label="Como..." name="How To"/>
<menu_item_call label="[SECOND_LIFE] Ajuda" name="Second Life Help"/>
<menu_item_call label="Denunciar abuso" name="Report Abuse"/>
<menu_item_call label="Relatar bug" name="Report Bug"/>
@@ -199,11 +204,10 @@
<menu_item_check label="Usar plugin de leitura de threads" name="Use Plugin Read Thread"/>
<menu_item_call label="Limpar cache de grupo" name="ClearGroupCache"/>
<menu_item_check label="Smoothing de mouse" name="Mouse Smoothing"/>
+ <menu_item_call label="Liberar teclas" name="Release Keys"/>
<menu label="Atalhos" name="Shortcuts">
<menu_item_call label="Imagem (L$[COST])..." name="Upload Image"/>
<menu_item_check label="Busca" name="Search"/>
- <menu_item_call label="Soltar objeto" name="Release Keys"/>
- <menu_item_call label="Interface tamanho padrão" name="Set UI Size to Default"/>
<menu_item_check label="Mostrar menu avançado - atalho antigo" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="Fechar janela" name="Close Window"/>
<menu_item_call label="Fechar todas as janelas" name="Close All Windows"/>
@@ -272,6 +276,7 @@
<menu_item_check label="Tipo de atualização" name="Update Type"/>
<menu_item_check label="Dados LOD" name="LOD Info"/>
<menu_item_check label="Fila de construção" name="Build Queue"/>
+ <menu_item_check label="Vetores de vento" name="Wind Vectors"/>
<menu_item_check label="Renderizar complexidade" name="rendercomplexity"/>
<menu_item_check label="Esculpir" name="Sculpt"/>
</menu>
@@ -281,7 +286,6 @@
<menu_item_check label="Iluminação e sombras" name="Lighting and Shadows"/>
<menu_item_check label="Sombras da projeção do sol/lua" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO e sombra suave" name="SSAO and Shadow Smoothing"/>
- <menu_item_check label="Iluminação global (fase experimental)" name="Global Illumination"/>
<menu_item_check label="Máscaras alpha automáticas (adiadas)" name="Automatic Alpha Masks (deferred)"/>
<menu_item_check label="Máscaras alpha automáticas (sem adiar)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Texturas de animação" name="Animation Textures"/>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index d3547beeb3..2c5ccd6e19 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -973,7 +973,7 @@ Oferecer amizade para [NAME]?
</form>
</notification>
<notification name="RemoveFromFriends">
- Remover &lt;nolink&gt;[NAME]&lt;/nolink&gt; da sua lista de amigos?
+ Deseja remover &lt;nolink&gt;[NAME]&lt;/nolink&gt; da sua lista de amigos?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Remover"/>
</notification>
<notification name="RemoveMultipleFromFriends">
@@ -1099,8 +1099,13 @@ Doar este terreno de [AREA] m² para o grupo &apos;[GROUP_NAME]&apos;?
<notification name="DisplaySetToSafe">
Configurações de display foram ajustadas para níveis de segurança porque você especificou -- opção de segurança.
</notification>
- <notification name="DisplaySetToRecommended">
- Configurações de display foram ajustadas para nível recomendado baseado na configuração do seu sistema.
+ <notification name="DisplaySetToRecommendedGPUChange">
+ As configurações de tela foram definidas nos níveis recomendados porque sua placa de vídeo foi alterada
+de &apos;[LAST_GPU]&apos;
+para &apos;[THIS_GPU]&apos;
+ </notification>
+ <notification name="DisplaySetToRecommendedFeatureChange">
+ As configurações de tela foram definidas nos níveis recomendados por causa de uma alteração no subsistema de renderização.
</notification>
<notification name="ErrorMessage">
[ERROR_MESSAGE]
@@ -1419,7 +1424,7 @@ Para instalar a atualização, será preciso reiniciar o [APP_NAME].
<usetemplate ignoretext="Confirmar antes de devolver objetos a seus donos" name="okcancelignore" notext="Cancelar" yestext="Retornar"/>
</notification>
<notification name="GroupLeaveConfirmMember">
- Você é atualmente um membro do grupo [GROUP].
+ Você é atualmente um membro do grupo &lt;nolink&gt;[GROUP]&lt;/nolink&gt;.
Sair do grupo?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Sair"/>
</notification>
@@ -1900,7 +1905,13 @@ Mover para o inventário o(s) item(s)?
<usetemplate ignoretext="Confirmar antes de sair" name="okcancelignore" notext="Não sair" yestext="Sair"/>
</notification>
<notification name="ConfirmRestoreToybox">
- Tem certeza que deseja restaurar seus botões e barras de ferramenta padrão?
+ Essa ação irá restaurar os botões e barras de ferramenta padrão.
+
+Não é possível desfazer essa ação.
+ <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="ConfirmClearAllToybox">
+ Essa ação fará com que todos os botões voltem para a caixa de ferramentas e suas barras de ferramentas ficarão vazias.
Não é possível desfazer essa ação.
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
@@ -2225,14 +2236,16 @@ Selecione só um objeto.
Seu cartão de visita foi negado.
</notification>
<notification name="TeleportToLandmark">
- Para se teletransportar para lugares como &apos;[NAME]&apos;, abra o painel &apos;Lugares&apos; à direita da tela e selecione a guia Marcos.
-Basta clicar em qualquer marco e depois clicar em &apos;Teletransportar&apos; na parte inferior da tela.
-(Também é possível clicar duas vezes no marco, ou clicar no marco com o botão direito e selecionar &apos;Teletransportar&apos;.)
+ Para se teletransportar para locais como &apos;[NAME]&apos;, clique no botão &quot;Lugares&quot;,
+ e selecione a guia Marcos na janela que é exibida. Clique em qualquer
+ marco para selecioná-lo e em seguida em &apos;Teletransportar&apos; na parte inferior da tela.
+ (Também é possível clicar duas vezes sobre o marco ou clicar com o botão direito do mouse sobre ele
+ e selecionar &apos;Teletransportar&apos;.)
</notification>
<notification name="TeleportToPerson">
- Para entrar em contato com residentes como &apos;&apos;[NAME]&apos;, abra o painel &apos;Pessoas&apos; à direita da tela.
-Selecione o residente da lista e clique em &apos;MI&apos; na parte de baixo do painel.
-(Também é possível clicar duas vezes no nome, ou clicar no nome com o botão direito e selecionar &apos;MI&apos;.)
+ Para entrar em contato com residentes como &apos;[NAME]&apos;, clique no botão &quot;Pessoas&quot;, selecione um residente na janela que é exibida e clique em &apos;MI&apos; na
+ parte inferior da janela.
+ (Também é possível clicar duas vezes no nome, ou clicar no nome com o botão direito e selecionar &apos;MI&apos;.)
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Impossível selecionar terra nas fronteiras do servidor. Tente selecionar um pedaço menor de terra.
@@ -2252,6 +2265,9 @@ Selecione o residente da lista e clique em &apos;MI&apos; na parte de baixo do p
<notification name="PaymentSent">
[MESSAGE]
</notification>
+ <notification name="PaymentFailure">
+ [MESSAGE]
+ </notification>
<notification name="EventNotification">
Notificação de evento:
@@ -2501,10 +2517,10 @@ Cada um pode ver o status do outro (definição padrão).
</form>
</notification>
<notification name="FriendshipAccepted">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; aceitou seu convite de amizade.
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; aceitou sua oferta de amizade.
</notification>
<notification name="FriendshipDeclined">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; recusou seu convite de amizade
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; rejeitou sua oferta de amizade.
</notification>
<notification name="FriendshipAcceptedByMe">
Oferta de amizada aceita.
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_skin.xml b/indra/newview/skins/default/xui/pt/panel_edit_skin.xml
index f3d88123f2..d00aa2dc66 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_skin.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skin_panel">
<panel name="avatar_skin_color_panel">
- <texture_picker label="Tatuagens na cabeça" name="Head Tattoos" tool_tip="Selecionar imagem"/>
- <texture_picker label="Tatuagem parte de cima" name="Upper Tattoos" tool_tip="Selecionar imagem"/>
- <texture_picker label="Tatuagem de baixo" name="Lower Tattoos" tool_tip="Selecionar imagem"/>
+ <texture_picker label="Cabeça" name="Head" tool_tip="Selecionar imagem"/>
+ <texture_picker label="Cintura acima" name="Upper Body" tool_tip="Selecionar imagem"/>
+ <texture_picker label="Cintura para baixo" name="Lower Body" tool_tip="Selecionar imagem"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/pt/panel_postcard_message.xml b/indra/newview/skins/default/xui/pt/panel_postcard_message.xml
new file mode 100644
index 0000000000..9cde810430
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_postcard_message.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_message">
+ <text name="to_label">
+ Para:
+ </text>
+ <text name="name_label">
+ De:
+ </text>
+ <text name="subject_label">
+ Assunto:
+ </text>
+ <line_editor label="Digite aqui o assunto." name="subject_form"/>
+ <text name="msg_label">
+ Mensagem:
+ </text>
+ <text_editor name="msg_form">
+ Digite aqui a mensagem.
+ </text_editor>
+ <button label="Cancelar" name="cancel_btn"/>
+ <button label="Enviar" name="send_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_postcard_settings.xml b/indra/newview/skins/default/xui/pt/panel_postcard_settings.xml
new file mode 100644
index 0000000000..3088b9a996
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_postcard_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_settings">
+ <combo_box label="Resolução" name="postcard_size_combo">
+ <combo_box.item label="Janela atual" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Customizado" name="Custom"/>
+ </combo_box>
+ <layout_stack name="postcard_image_params_ls">
+ <layout_panel name="postcard_image_size_lp">
+ <spinner label="Largura" name="postcard_snapshot_width"/>
+ <spinner label="Altura" name="postcard_snapshot_height"/>
+ <check_box label="Limitar proporções" name="postcard_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="postcard_image_format_quality_lp">
+ <slider label="Qualidade da imagem" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
index f98659aa73..c5a4febb0e 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
@@ -29,30 +29,5 @@
<check_box label="Bate-papos de MI" name="EnableIMChatPopups" tool_tip="Exibir pop-up de mensagens instantâneas novas"/>
<spinner label="Transição de avisos de bate-papos por perto:" name="nearby_toasts_lifetime"/>
<spinner label="Transição de avisos de bate-papos por perto:" name="nearby_toasts_fadingtime"/>
- <check_box name="translate_chat_checkbox"/>
- <text name="translate_chb_label">
- Traduzir bate-papo automaticamente
- </text>
- <text name="translate_language_text">
- Traduzir bate-papo para:
- </text>
- <combo_box name="translate_language_combobox">
- <combo_box.item label="Padrão" name="System Default Language"/>
- <combo_box.item label="English (Inglês)" name="English"/>
- <combo_box.item label="Dansk (Dinamarquês)" name="Danish"/>
- <combo_box.item label="Deutsch (Alemão)" name="German"/>
- <combo_box.item label="Español (Espanhol)" name="Spanish"/>
- <combo_box.item label="Français (Francês)" name="French"/>
- <combo_box.item label="Italiano (Italiano)" name="Italian"/>
- <combo_box.item label="Magyar (Húngaro)" name="Hungarian"/>
- <combo_box.item label="Nederlands (Holandês)" name="Dutch"/>
- <combo_box.item label="Polski (Polonês)" name="Polish"/>
- <combo_box.item label="Português (Português)" name="Portugese"/>
- <combo_box.item label="Русский (Russo)" name="Russian"/>
- <combo_box.item label="Türkçe (Turco)" name="Turkish"/>
- <combo_box.item label="Українська (Ucraniano)" name="Ukrainian"/>
- <combo_box.item label="中文 (简体) (Chinês)" name="Chinese"/>
- <combo_box.item label="日本語 (Japonês)" name="Japanese"/>
- <combo_box.item label="한국어 (Coreano)" name="Korean"/>
- </combo_box>
+ <button label="Configurações de tradução de bate-papo" name="ok_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
index 9259c0ed56..ebbd63138a 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
@@ -15,7 +15,7 @@
Web:
</text>
<radio_group name="use_external_browser">
- <radio_item label="Usar meu navegador (IE, Firefox, Safari)" name="external" tool_tip="Use o navegador incluso para consultar a ajuda, abrir links da web, etc. Uso em tela inteira não recomendado." value="1"/>
+ <radio_item label="Usar meu navegador (IE, Firefox, Safari)" name="external" tool_tip="Use o navegador incluso para consultar a ajuda, abrir links da web, etc. Uso em tela inteira não recomendado." value="true"/>
<radio_item label="Usar navegador incluso" name="internal" tool_tip="Use este navegador para consultar a ajuda, abrir links da web, etc. As janelas abrem dentro do [APP_NAME]." value=""/>
</radio_group>
<check_box initial_value="true" label="Habilitar plugins" name="browser_plugins_enabled"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml
new file mode 100644
index 0000000000..3c4bb18687
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_inventory">
+ <text name="title">
+ Salvar no meu inventário
+ </text>
+ <text name="hint_lbl">
+ Salvar uma imagem em seu inventário custa L$[UPLOAD_COST]. Para salvar sua imagem como uma textura, selecione um dos formatos quadrados.
+ </text>
+ <combo_box label="Resolução" name="texture_size_combo">
+ <combo_box.item label="Janela atual" name="CurrentWindow"/>
+ <combo_box.item label="Pequeno (128x128)" name="Small(128x128)"/>
+ <combo_box.item label="Médio (256x256)" name="Medium(256x256)"/>
+ <combo_box.item label="Grande (512x512)" name="Large(512x512)"/>
+ <combo_box.item label="Customizado" name="Custom"/>
+ </combo_box>
+ <spinner label="Largura" name="inventory_snapshot_width"/>
+ <spinner label="Altura" name="inventory_snapshot_height"/>
+ <check_box label="Limitar proporções" name="inventory_keep_aspect_check"/>
+ <button label="Cancelar" name="cancel_btn"/>
+ <button label="Salvar" name="save_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_local.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_local.xml
new file mode 100644
index 0000000000..36b5b0cbe6
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_snapshot_local.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_local">
+ <text name="title">
+ Salvar no meu PC
+ </text>
+ <combo_box label="Resolução" name="local_size_combo">
+ <combo_box.item label="Janela atual" name="CurrentWindow"/>
+ <combo_box.item label="320x240" name="320x240"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="1280x1024" name="1280x1024"/>
+ <combo_box.item label="1600x1200" name="1600x1200"/>
+ <combo_box.item label="Customizado" name="Custom"/>
+ </combo_box>
+ <layout_stack name="local_image_params_ls">
+ <layout_panel name="local_image_size_lp">
+ <spinner label="Largura" name="local_snapshot_width"/>
+ <spinner label="Altura" name="local_snapshot_height"/>
+ <check_box label="Limitar proporções" name="local_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="local_image_format_quality_lp">
+ <combo_box label="Formato" name="local_format_combo">
+ <combo_box.item label="PNG (sem perda)" name="PNG"/>
+ <combo_box.item label="JPEG" name="JPEG"/>
+ <combo_box.item label="BMP (sem perda)" name="BMP"/>
+ </combo_box>
+ <slider label="Qualidade da imagem" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <button label="Cancelar" name="cancel_btn"/>
+ <flyout_button label="Salvar" name="save_btn" tool_tip="Salvar imagem em um arquivo">
+ <flyout_button.item label="Salvar" name="save_item"/>
+ <flyout_button.item label="Salvar como..." name="saveas_item"/>
+ </flyout_button>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml
new file mode 100644
index 0000000000..7f1452e992
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_options">
+ <button label="Postar no feed do meu perfil" name="save_to_profile_btn"/>
+ <button label="E-mail" name="save_to_email_btn"/>
+ <button label="Salvar em Meu inventário (L$[AMOUNT])" name="save_to_inventory_btn"/>
+ <button label="Salvar no meu PC" name="save_to_computer_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml
new file mode 100644
index 0000000000..12a648f600
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_postcard">
+ <string name="default_subject">
+ Postal do [SECOND_LIFE].
+ </string>
+ <string name="default_message">
+ Confira!
+ </string>
+ <string name="upload_message">
+ Enviando...
+ </string>
+ <text name="title">
+ E-mail
+ </text>
+ <button label="Mensagem" name="message_btn"/>
+ <button label="Configurações" name="settings_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_profile.xml
new file mode 100644
index 0000000000..095b8fc75d
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_snapshot_profile.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_profile">
+ <text name="title">
+ Postar no feed do meu perfil
+ </text>
+ <combo_box label="Resolução" name="profile_size_combo">
+ <combo_box.item label="Janela atual" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Customizado" name="Custom"/>
+ </combo_box>
+ <layout_stack name="profile_image_params_ls">
+ <layout_panel name="profile_image_size_lp">
+ <spinner label="Largura" name="profile_snapshot_width"/>
+ <spinner label="Altura" name="profile_snapshot_height"/>
+ <check_box label="Limitar proporções" name="profile_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="profile_image_metadata_lp">
+ <text name="caption_label">
+ Legenda:
+ </text>
+ <check_box initial_value="true" label="Incluir local" name="add_location_cb"/>
+ </layout_panel>
+ </layout_stack>
+ <button label="Cancelar" name="cancel_btn"/>
+ <button label="Postar" name="post_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_status_bar.xml b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
index d5a3258ddc..22853f0643 100644
--- a/indra/newview/skins/default/xui/pt/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
@@ -18,7 +18,7 @@
<panel name="balance_bg">
<text name="balance" tool_tip="Atualizar saldo de L$" value="L$20"/>
<button label="Comprar L$" name="buyL" tool_tip="Comprar mais L$"/>
- <button label="Comprar" name="goShop" tool_tip="Abrir Mercado do Second Life"/>
+ <button label="Comprar" name="goShop" tool_tip="Abrir Mercado do Second Life" width="80"/>
</panel>
<text name="TimeText" tool_tip="Hora atual (Pacífico)">
24:00 AM PST
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index 6b4835e819..4babd9cc43 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -1160,7 +1160,7 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar
Você não possui uma cópia desta textura no seu inventário
</string>
<string name="InventoryInboxNoItems">
- Compras do marketplace serão entregues aqui.
+ Quando você comprar ou receber um item, ele aparecerá aqui para que você possa arrastá-lo para uma pasta em seu inventário ou excluí-lo caso não queira mantê-lo.
</string>
<string name="MarketplaceURL">
http://marketplace.[DOMAIN_NAME]
@@ -1352,6 +1352,9 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar
<string name="no_attachments">
Nenhum anexo vestido
</string>
+ <string name="Attachments remain">
+ Anexos ([COUNT] slots permanecem)
+ </string>
<string name="Buy">
Comprar
</string>
@@ -1478,6 +1481,12 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar
<string name="Right Pec">
Peitoral D
</string>
+ <string name="Neck">
+ Pescoço
+ </string>
+ <string name="Avatar Center">
+ Centro do avatar
+ </string>
<string name="Invalid Attachment">
Ponto de encaixe inválido
</string>
@@ -3897,6 +3906,18 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="you_paid_ldollars_no_name">
Você pagou L$[AMOUNT] por [REASON].
</string>
+ <string name="you_paid_failure_ldollars">
+ Você não pagou L$[AMOUNT] a [NAME] referentes a [REASON].
+ </string>
+ <string name="you_paid_failure_ldollars_no_info">
+ Você não pagou L$[AMOUNT].
+ </string>
+ <string name="you_paid_failure_ldollars_no_reason">
+ Você não pagou L$[AMOUNT] a [NAME].
+ </string>
+ <string name="you_paid_failure_ldollars_no_name">
+ Você não pagou L$[AMOUNT] referentes a [REASON].
+ </string>
<string name="for item">
por [ITEM]
</string>
@@ -4307,6 +4328,12 @@ Tente colocar o caminho do editor entre aspas.
<string name="ExternalEditorFailedToRun">
Falha de execução do editor externo.
</string>
+ <string name="TranslationFailed">
+ Falha na tradução: [REASON]
+ </string>
+ <string name="TranslationResponseParseError">
+ Erro ao analisar resposta de tradução.
+ </string>
<string name="Esc">
Esc
</string>
@@ -4677,7 +4704,7 @@ Tente colocar o caminho do editor entre aspas.
Mini Mapa
</string>
<string name="Command_Move_Label">
- Mover
+ Andar/correr/voar
</string>
<string name="Command_People_Label">
Pessoas
@@ -4704,10 +4731,10 @@ Tente colocar o caminho do editor entre aspas.
Falar
</string>
<string name="Command_View_Label">
- Exibir
+ Controles da câmera
</string>
<string name="Command_Voice_Label">
- Voz próxima
+ Configurações de voz
</string>
<string name="Command_AboutLand_Tooltip">
Informações sobre o terreno que você está visitando
@@ -4779,7 +4806,16 @@ Tente colocar o caminho do editor entre aspas.
Alterar o ângulo da câmera
</string>
<string name="Command_Voice_Tooltip">
- Pessoas próximas com recursos de voz
+ Controles de volume das chamadas e pessoas próximas a você no mundo virtual
+ </string>
+ <string name="Toolbar_Bottom_Tooltip">
+ atualmente na sua barra de ferramentas inferior
+ </string>
+ <string name="Toolbar_Left_Tooltip">
+ atualmente na sua barra de ferramentas esquerda
+ </string>
+ <string name="Toolbar_Right_Tooltip">
+ atualmente na sua barra de ferramentas direita
</string>
<string name="Retain%">
Reter%
@@ -4805,4 +4841,19 @@ Tente colocar o caminho do editor entre aspas.
<string name="Normal">
Normal
</string>
+ <string name="snapshot_quality_very_low">
+ Muito baixo
+ </string>
+ <string name="snapshot_quality_low">
+ Baixo
+ </string>
+ <string name="snapshot_quality_medium">
+ Médio
+ </string>
+ <string name="snapshot_quality_high">
+ Alto
+ </string>
+ <string name="snapshot_quality_very_high">
+ Muito alto
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/pt/teleport_strings.xml b/indra/newview/skins/default/xui/pt/teleport_strings.xml
index f8ded1ce69..3fb77a02d2 100644
--- a/indra/newview/skins/default/xui/pt/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/pt/teleport_strings.xml
@@ -19,8 +19,8 @@ Se você continuar a receber esta mensagem, por favor consulte o [SUPPORT_SITE].
Desculpe, não foi possível para o sistema executar o teletransporte. Tente novamente dentro de alguns instantes.
</message>
<message name="NoHelpIslandTP">
- Você não pode se tele-transportar de volta à Ilha de Welcome.
-Vá para a Ilha de Welcome Pública para repetir este tutorial.
+ Não é possível se teletransportar de volta à Ilha Welcome.
+Vá para a &apos;Ilha Welcome Pública&apos; para repetir o tutorial.
</message>
<message name="noaccess_tport">
Desculpe, você não tem acesso ao destino deste teletransporte.
diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml
index deb6be319c..119f104906 100644
--- a/indra/newview/skins/default/xui/ru/floater_about.xml
+++ b/indra/newview/skins/default/xui/ru/floater_about.xml
@@ -63,32 +63,34 @@
<panel label="Лицензии" name="licenses_panel">
<text_editor name="credits_editor">
3Dconnexion SDK (C) 1992-2007 3Dconnexion
-APR (C) 2000-2004 The Apache Software Foundation
-Collada DOM (C) 2005 Sony Computer Entertainment Inc.cURL (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ APR (C) 2000-2004 The Apache Software Foundation
+ Collada DOM (C) 2005 Sony Computer Entertainment Inc.
+ cURL (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ DBus/dbus-glib (C) 2002, 2003 CodeFactory AB / (C) 2003, 2004 Red Hat, Inc.
+ expat (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+ FreeType (C) 1996-2002, The FreeType Project (www.freetype.org).
+ GL (C) 1999-2004 Brian Paul.
+ GLOD (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Университет Джона Гопкинса и David Luebke, Brenden Schubert, Университет Вирджинии.
+ google-perftools (c) 2005, Google Inc.
+ Havok.com(TM) (C) 1999-2001, Telekinesys Research Limited.
+ jpeg2000 (C) 2001, David Taubman, Университет Нового Южного Уэльса (UNSW)
+ jpeglib (C) 1991-1998, Thomas G. Lane.
+ ogg/vorbis (C) 2001, Xiphophorus
+ OpenSSL (C) 1998-2002 The OpenSSL Project.
+ PCRE (c) 1997-2008, Кембриджский университет
+ SDL (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+ SSLeay (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ xmlrpc-epi (C) 2000 Epinions, Inc.
+ zlib (C) 1995-2002 Jean-loup Gailly и Mark Adler.
+ google-perftools (c) 2005, Google Inc.
-DBus/dbus-glib (C) 2002, 2003 CodeFactory AB / (C) 2003, 2004 Red Hat, Inc.
-expat (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
-FreeType (C) 1996-2002, The FreeType Project (www.freetype.org).
-GL (C) 1999-2004 Brian Paul.
-GLOD (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University и David Luebke, Brenden Schubert, Университет Вирджиинии.
-google-perftools (c) 2005, Google Inc.
-Havok.com(TM) (C) 1999-2001, Telekinesys Research Limited.
-jpeg2000 (C) 2001, David Taubman, Университет Нового Южного Уэльса (UNSW)
-jpeglib (C) 1991-1998, Thomas G. Lane.
-ogg/vorbis (C) 2001, Xiphophorus
-OpenSSL (C) 1998-2002 The OpenSSL Project.
-PCRE (c) 1997-2008, Кембриджский университет
-SDL (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
-SSLeay (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-xmlrpc-epi (C) 2000 Epinions, Inc.
-zlib (C) 1995-2002 Jean-loup Gailly и Mark Adler.
-google-perftools (c) 2005, Google Inc.
+ В клиенте Second Life используется технология Havok (TM) Physics. (C) 1999-2010 Havok.com Inc. (и лицензиары компании). Все права защищены. Подробнее см. веб-сайт www.havok.com.
-В клиенте Second Life используется технология Havok (TM) Physics. (C) 1999-2010 Havok.com Inc. (и лицензиары компании). Все права защищены. Подробнее см. веб-сайт www.havok.com.
+ Это программное обеспечение содержит исходный код, предоставленный корпорацией NVIDIA.
-Все права защищены. Подробные сведения см. в файле licenses.txt.
+ Все права защищены. Подробные сведения см. в файле licenses.txt.
-Кодирование звука для голосового чата: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1, Приложение C)
+ Кодирование звука для голосового чата: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
</text_editor>
</panel>
</tab_container>
diff --git a/indra/newview/skins/default/xui/ru/floater_about_land.xml b/indra/newview/skins/default/xui/ru/floater_about_land.xml
index 3c278fce52..46414a530a 100644
--- a/indra/newview/skins/default/xui/ru/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/ru/floater_about_land.xml
@@ -129,7 +129,7 @@
Посещаемость:
</text>
<text name="DwellText">
- 0
+ Загрузка...
</text>
<button label="Купить землю" name="Buy Land..."/>
<button label="Продать для Linden" name="Linden Sale..." tool_tip="Земля должна быть в собственности, иметь заданное содержимое и не быть выставленной на аукцион,"/>
@@ -307,13 +307,15 @@
Не толкать (настройки региона)
</panel.string>
<panel.string name="see_avs_text">
- Видеть жителей этого участка и общаться с ними в чате
+ Аватары с других участков могут видеть
</panel.string>
<text name="allow_label">
Позволить другим жителям:
</text>
- <check_box label="Изменить ландшафт" name="edit land check" tool_tip="Если отмечено, вашу землю сможет терраформировать кто угодно. Лучше не отмечать, так как вы всегда можете изменить вашу землю."/>
- <check_box label="Полет" name="check fly" tool_tip="Если отмечено, жители смогут летать над вашей землей. Если не отметить, они смогут только прилетать и пролетать мимо земли."/>
+ <text name="allow_label0">
+ Полет:
+ </text>
+ <check_box label="Все" name="check fly" tool_tip="Если отмечено, жители смогут летать над вашей землей. Если не отметить, они смогут только прилетать и пролетать мимо земли."/>
<text name="allow_label2">
Строительство:
</text>
@@ -329,9 +331,6 @@
</text>
<check_box label="Все" name="check other scripts"/>
<check_box label="Группа" name="check group scripts"/>
- <text name="land_options_label">
- Параметры земли:
- </text>
<check_box label="Безопасно (нет повреждений)" name="check safe" tool_tip="Если отмечено, то земля считается безопасной, отключены боевые повреждения. Если не отмечено, то боевые повреждения включены."/>
<check_box label="Не толкать" name="PushRestrictCheck" tool_tip="Запрещает скриптам функцию толкания. Этот параметр может оказаться полезным для предотвращения нежелательного поведения на вашей земле."/>
<check_box label="Показать место в поиске (L$30/неделя)" name="ShowDirectoryCheck" tool_tip="Позволить людям видеть участок в результатах поиска"/>
@@ -372,9 +371,9 @@
</text>
<texture_picker name="snapshot_ctrl" tool_tip="Щелкните для выбора изображения"/>
<text name="allow_label5">
- Позволить жителям с других участков:
+ аватары на этом участке и общаться с ними
</text>
- <check_box label="Видны аватары" name="SeeAvatarsCheck" tool_tip="Жители с других участков могут видеть жителей этого участка и общаться с ними в чате (вы также сможете видеть жителей с других участков и общаться с ними)."/>
+ <check_box label="Видны аватары" name="SeeAvatarsCheck" tool_tip="Аватары с других участков смогут видеть аватары на этом участке и общаться с ними в чате, а вы также сможете видеть их и общаться с ними."/>
<text name="landing_point">
В точку телепортации: [LANDING]
</text>
diff --git a/indra/newview/skins/default/xui/ru/floater_avatar.xml b/indra/newview/skins/default/xui/ru/floater_avatar.xml
index 6bdf819880..b480af9345 100644
--- a/indra/newview/skins/default/xui/ru/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/ru/floater_avatar.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Avatar" title="ВЫБОР АВАТАРА"/>
+<floater name="Avatar" title="ВЫБЕРИТЕ АВАТАР"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_buy_currency.xml b/indra/newview/skins/default/xui/ru/floater_buy_currency.xml
index 7d34ca3274..87e8bd524e 100644
--- a/indra/newview/skins/default/xui/ru/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/ru/floater_buy_currency.xml
@@ -46,7 +46,7 @@
L$ [AMT]
</text>
<text name="currency_links">
- [http://www.secondlife.com/my/account/payment_method_management.php способ оплаты] | [http://www.secondlife.com/my/account/currency.php валюта]
+ [http://www.secondlife.com/my/account/payment_method_management.php способ оплаты] | [http://www.secondlife.com/my/account/currency.php деньги]
</text>
<text name="exchange_rate_note">
Повторно введите сумму, чтобы увидеть новый обменный курс.
diff --git a/indra/newview/skins/default/xui/ru/floater_camera.xml b/indra/newview/skins/default/xui/ru/floater_camera.xml
index 945a63c0eb..52e7c62e06 100644
--- a/indra/newview/skins/default/xui/ru/floater_camera.xml
+++ b/indra/newview/skins/default/xui/ru/floater_camera.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="camera_floater" title="КАМЕРА">
+<floater name="camera_floater" title="УПРАВЛЕНИЕ КАМЕРОЙ">
<floater.string name="rotate_tooltip">
Повернуть камеру вокруг точки фокусировки
</floater.string>
diff --git a/indra/newview/skins/default/xui/ru/floater_chat_bar.xml b/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
index eceab1775a..79b7b033fb 100644
--- a/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="chat_bar" title="ЛОКАЛЬНЫЙ ЧАТ">
- <panel>
+ <panel name="bottom_panel">
<line_editor label="Щелкните здесь для общения." name="chat_box" tool_tip="Нажмите Enter, чтобы сказать, Ctrl+Enter, чтобы прокричать"/>
<button name="show_nearby_chat" tool_tip="Показать/скрыть лог локального чата"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml b/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml
index 0fefb76ea5..7400f1df3b 100644
--- a/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml
@@ -4,7 +4,7 @@
Фильтрация:
</text>
<check_box label="Анизотропная фильтрация (медленнее, если включено)" name="ani"/>
- <text name="Antialiasing:">
+ <text name="antialiasing label">
Сглаживание:
</text>
<combo_box label="Сглаживание" name="fsaa">
diff --git a/indra/newview/skins/default/xui/ru/floater_model_preview.xml b/indra/newview/skins/default/xui/ru/floater_model_preview.xml
index 31517e722d..5bb96b8de4 100644
--- a/indra/newview/skins/default/xui/ru/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/ru/floater_model_preview.xml
@@ -4,6 +4,9 @@
<string name="status_parse_error">
Ошибка. Проблема при анализе файла DAE – см. подробности в журнале.
</string>
+ <string name="status_material_mismatch">
+ Ошибка. Материал модели не входит в эталонную модель.
+ </string>
<string name="status_reading_file">
Загрузка...
</string>
@@ -137,7 +140,7 @@
</panel>
<panel name="physics analysis">
<text name="method_label">
- Шаг 2. Анализ
+ 2 этап. Анализ
</text>
<text name="analysis_method_label">
Метод:
diff --git a/indra/newview/skins/default/xui/ru/floater_model_wizard.xml b/indra/newview/skins/default/xui/ru/floater_model_wizard.xml
index ef2fe8e5a5..5b03dd2c73 100644
--- a/indra/newview/skins/default/xui/ru/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/ru/floater_model_wizard.xml
@@ -20,6 +20,9 @@
Выберите файл модели для передачи
</text>
<button label="Обзор..." label_selected="Обзор..." name="browse"/>
+ <text name="Model types">
+ В Second Life поддерживаются файлы COLLADA (.dae)
+ </text>
<text name="dimensions">
X Y Z
</text>
diff --git a/indra/newview/skins/default/xui/ru/floater_moveview.xml b/indra/newview/skins/default/xui/ru/floater_moveview.xml
index 6e01f997e1..cb1fda1a1f 100644
--- a/indra/newview/skins/default/xui/ru/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/ru/floater_moveview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="move_floater" title="ПЕРЕМЕЩЕНИЕ">
+<floater name="move_floater" title="ХОДЬБА / БЕГ / ПОЛЕТ">
<string name="walk_forward_tooltip">
Идти вперед (нажмите стрелку вверх или клавишу W)
</string>
diff --git a/indra/newview/skins/default/xui/ru/floater_snapshot.xml b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
index f85d602be7..7e88630b32 100644
--- a/indra/newview/skins/default/xui/ru/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
@@ -3,72 +3,63 @@
<floater.string name="unknown">
неизвестно
</floater.string>
- <radio_group label="Тип снимка" name="snapshot_type_radio">
- <radio_item label="Электронная почта" name="postcard"/>
- <radio_item label="Мой инвентарь (L$[AMOUNT])" name="texture"/>
- <radio_item label="Сохранить на моем компьютере" name="local"/>
- </radio_group>
+ <string name="postcard_progress_str">
+ Отправка письма
+ </string>
+ <string name="profile_progress_str">
+ Публикация
+ </string>
+ <string name="inventory_progress_str">
+ Сохранение в -инвентарь
+ </string>
+ <string name="local_progress_str">
+ Сохранение на компьютере
+ </string>
+ <string name="profile_succeeded_str">
+ Изображение отправлено
+ </string>
+ <string name="postcard_succeeded_str">
+ Письмо отправлено!
+ </string>
+ <string name="inventory_succeeded_str">
+ Сохранено в инвентаре!
+ </string>
+ <string name="local_succeeded_str">
+ Сохранено на компьютере!
+ </string>
+ <string name="profile_failed_str">
+ Не удалось передать изображение в ваш профиль.
+ </string>
+ <string name="postcard_failed_str">
+ Не удалось отправить письмо.
+ </string>
+ <string name="inventory_failed_str">
+ Не удалось сохранить в инвентаре.
+ </string>
+ <string name="local_failed_str">
+ Не удалось сохранить на компьютере.
+ </string>
+ <button name="advanced_options_btn" tool_tip="Дополнительные параметры"/>
+ <text name="image_res_text">
+ [WIDTH] x [HEIGHT] пикс.
+ </text>
<text name="file_size_label">
[SIZE] КБ
</text>
- <button label="Послать" name="send_btn"/>
- <button label="Сохранить (L$[AMOUNT])" name="upload_btn"/>
- <flyout_button label="Сохранить" name="save_btn" tool_tip="Сохранить изображение в файл">
- <flyout_button.item label="Сохранить" name="save_item"/>
- <flyout_button.item label="Сохранить как..." name="saveas_item"/>
- </flyout_button>
- <button label="Больше" name="more_btn" tool_tip="Дополнительные параметры"/>
- <button label="Меньше" name="less_btn" tool_tip="Дополнительные параметры"/>
- <button label="Отмена" name="discard_btn"/>
- <text name="type_label2">
- Размер
- </text>
- <text name="format_label">
- Формат
- </text>
- <combo_box label="Разрешение" name="postcard_size_combo">
- <combo_box.item label="Текущее окно" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="Задать" name="Custom"/>
- </combo_box>
- <combo_box label="Разрешение" name="texture_size_combo">
- <combo_box.item label="Текущее окно" name="CurrentWindow"/>
- <combo_box.item label="Маленький (128x128)" name="Small(128x128)"/>
- <combo_box.item label="Средний (256x256)" name="Medium(256x256)"/>
- <combo_box.item label="Большой (512x512)" name="Large(512x512)"/>
- <combo_box.item label="Задать" name="Custom"/>
- </combo_box>
- <combo_box label="Разрешение" name="local_size_combo">
- <combo_box.item label="Текущее окно" name="CurrentWindow"/>
- <combo_box.item label="320x240" name="320x240"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1280x1024" name="1280x1024"/>
- <combo_box.item label="1600x1200" name="1600x1200"/>
- <combo_box.item label="Задать" name="Custom"/>
- </combo_box>
- <combo_box label="Формат" name="local_format_combo">
- <combo_box.item label="PNG" name="PNG"/>
- <combo_box.item label="JPEG" name="JPEG"/>
- <combo_box.item label="BMP" name="BMP"/>
- </combo_box>
- <spinner label="Ширина" name="snapshot_width"/>
- <spinner label="Высота" name="snapshot_height"/>
- <check_box label="Сохранять пропорции" name="keep_aspect_check"/>
- <slider label="Качество изображения" name="image_quality_slider"/>
- <text name="layer_type_label">
- Захват:
- </text>
- <combo_box label="Слои изображения" name="layer_types">
- <combo_box.item label="Цвета" name="Colors"/>
- <combo_box.item label="Глубина" name="Depth"/>
- </combo_box>
- <check_box label="Интерфейс" name="ui_check"/>
- <check_box label="HUD" name="hud_check"/>
- <check_box label="Оставить окно открытым" name="keep_open_check"/>
- <check_box label="Стоп-кадр (полноэкранный)" name="freeze_frame_check"/>
- <check_box label="Автообновление" name="auto_snapshot_check"/>
+ <panel name="advanced_options_panel">
+ <text name="advanced_options_label">
+ ДОПОЛНИТЕЛЬНЫЕ ПАРАМЕТРЫ
+ </text>
+ <text name="layer_type_label">
+ Захват:
+ </text>
+ <combo_box label="Слои изображения" name="layer_types">
+ <combo_box.item label="Цвета" name="Colors"/>
+ <combo_box.item label="Глубина" name="Depth"/>
+ </combo_box>
+ <check_box label="Интерфейс" name="ui_check"/>
+ <check_box label="Данные в игре" name="hud_check"/>
+ <check_box label="Стоп-кадр (полноэкранный)" name="freeze_frame_check"/>
+ <check_box label="Автообновление" name="auto_snapshot_check"/>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_toybox.xml b/indra/newview/skins/default/xui/ru/floater_toybox.xml
index 8d7431d393..a4754ad7ab 100644
--- a/indra/newview/skins/default/xui/ru/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/ru/floater_toybox.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Toybox" title="НАСТРОИТЬ ПАНЕЛИ ИНСТРУМЕНТОВ">
+<floater name="Toybox" title="КНОПКИ ПАНЕЛИ ИНСТРУМЕНТОВ">
<text name="toybox label 1">
Добавьте или удалите кнопки, перетягивая их на панели инструментов или с них.
</text>
<text name="toybox label 2">
Кнопки будут отображены в исходном виде или в виде значков, в зависимости от настроек каждой панели инструментов.
</text>
+ <button label="Очистить все панели" label_selected="Очистить все панели" name="btn_clear_all"/>
<button label="Вернуть стандартные" label_selected="Вернуть стандартные" name="btn_restore_defaults"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_translation_settings.xml b/indra/newview/skins/default/xui/ru/floater_translation_settings.xml
new file mode 100644
index 0000000000..ad280a50dd
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_translation_settings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_translation_settings" title="НАСТРОЙКИ ПЕРЕВОДА ЧАТА">
+ <string name="bing_api_key_not_verified">
+ Bing appID не подтвержден. Повторите попытку.
+ </string>
+ <string name="google_api_key_not_verified">
+ Ключ Google API не подтвержден. Повторите попытку.
+ </string>
+ <string name="bing_api_key_verified">
+ Bing appID подтвержден.
+ </string>
+ <string name="google_api_key_verified">
+ Ключ Google API подтвержден.
+ </string>
+ <check_box label="Включить машинный перевод при чате" name="translate_chat_checkbox"/>
+ <text name="translate_language_label">
+ Переводить чат на:
+ </text>
+ <combo_box name="translate_language_combo">
+ <combo_box.item label="язык системы" name="System Default Language"/>
+ <combo_box.item label="английский" name="English"/>
+ <combo_box.item label="датский" name="Danish"/>
+ <combo_box.item label="немецкий" name="German"/>
+ <combo_box.item label="испанский" name="Spanish"/>
+ <combo_box.item label="французский" name="French"/>
+ <combo_box.item label="итальянский" name="Italian"/>
+ <combo_box.item label="венгерский" name="Hungarian"/>
+ <combo_box.item label="нидерландский" name="Dutch"/>
+ <combo_box.item label="польский" name="Polish"/>
+ <combo_box.item label="португальский" name="Portugese"/>
+ <combo_box.item label="русский" name="Russian"/>
+ <combo_box.item label="турецкий" name="Turkish"/>
+ <combo_box.item label="украинский" name="Ukrainian"/>
+ <combo_box.item label="китайский" name="Chinese"/>
+ <combo_box.item label="японский" name="Japanese"/>
+ <combo_box.item label="корейский" name="Korean"/>
+ </combo_box>
+ <text name="tip">
+ Выберите сервис перевода:
+ </text>
+ <radio_group name="translation_service_rg">
+ <radio_item initial_value="bing" label="Bing Translator" name="bing"/>
+ <radio_item initial_value="google" label="Google Translate" name="google"/>
+ </radio_group>
+ <text name="bing_api_key_label">
+ Bing [http://www.bing.com/developers/createapp.aspx AppID]:
+ </text>
+ <button label="Подтвердить" name="verify_bing_api_key_btn"/>
+ <text name="google_api_key_label">
+ Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth Ключ API]:
+ </text>
+ <button label="Подтвердить" name="verify_google_api_key_btn"/>
+ <text name="google_links_text">
+ [http://code.google.com/apis/language/translate/v2/pricing.html Цены] | [https://code.google.com/apis/console Статистика]
+ </text>
+ <button label="OK" name="ok_btn"/>
+ <button label="Отмена" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_voice_controls.xml b/indra/newview/skins/default/xui/ru/floater_voice_controls.xml
index c1fb858d48..2b23086062 100644
--- a/indra/newview/skins/default/xui/ru/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/ru/floater_voice_controls.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_voice_controls" title="УПРАВЛЕНИЕ ГОЛОСОМ">
<string name="title_nearby">
- Настройки голоса
+ НАСТРОЙКИ ГОЛОСА
</string>
<string name="title_group">
- Звонок группе [GROUP]
+ ЗВОНОК ГРУППЕ [GROUP]
</string>
<string name="title_adhoc">
- Конференция
+ КОНФЕРЕНЦИЯ
</string>
<string name="title_peer_2_peer">
- Звонок пользователю [NAME]
+ ЗВОНОК ПОЛЬЗОВАТЕЛЮ [NAME]
</string>
<string name="no_one_near">
Нет никого с включенным голосом
diff --git a/indra/newview/skins/default/xui/ru/menu_toolbars.xml b/indra/newview/skins/default/xui/ru/menu_toolbars.xml
index e04a9ee57d..aa05dbc390 100644
--- a/indra/newview/skins/default/xui/ru/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/ru/menu_toolbars.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Toolbars Popup">
- <menu_item_call label="Выбор кнопок..." name="Chose Buttons"/>
+ <menu_item_call label="Удалить эту кнопку" name="Remove button"/>
+ <menu_item_call label="Кнопки панели инструментов..." name="Choose Buttons"/>
<menu_item_check label="Значки и подписи" name="icons_with_text"/>
<menu_item_check label="Только значки" name="icons_only"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml
index b9f403c04b..93d0166568 100644
--- a/indra/newview/skins/default/xui/ru/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml
@@ -1,12 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu_bar name="Main Menu">
<menu label="Я" name="Me">
- <menu_item_call label="Информационная панель..." name="Manage My Account"/>
<menu_item_call label="Профиль…" name="Profile"/>
<menu_item_call label="Внешность..." name="ChangeOutfit"/>
+ <menu_item_call label="Выберите аватар..." name="Avatar Picker"/>
<menu_item_check label="Инвентарь..." name="Inventory"/>
- <menu_item_check label="Жесты..." name="Gestures"/>
- <menu_item_check label="Голос..." name="ShowVoice"/>
+ <menu_item_call label="Новое окно инвентаря" name="NewInventoryWindow"/>
+ <menu_item_call label="Места..." name="Places"/>
+ <menu_item_call label="Подборка..." name="Picks"/>
+ <menu_item_call label="Управление камерой..." name="Camera Controls"/>
<menu label="Движение" name="Movement">
<menu_item_call label="Сесть" name="Sit Down Here"/>
<menu_item_check label="Полет" name="Fly"/>
@@ -20,34 +22,37 @@
<menu_item_call label="Запрос статуса администратора" name="Request Admin Options"/>
<menu_item_call label="Выход из статуса администратора" name="Leave Admin Options"/>
<menu_item_call label="Купить L$" name="Buy and Sell L$"/>
+ <menu_item_call label="Информационная панель аккаунта..." name="Manage My Account"/>
<menu_item_call label="Настройки..." name="Preferences"/>
- <menu_item_call label="Панели инструментов..." name="Toolbars"/>
+ <menu_item_call label="Кнопки панели инструментов..." name="Toolbars"/>
<menu_item_call label="Скрыть все элементы управления" name="Hide UI"/>
<menu_item_call label="Выход из [APP_NAME]" name="Quit"/>
</menu>
<menu label="Общение" name="Communicate">
- <menu_item_call label="Мои друзья" name="My Friends"/>
- <menu_item_call label="Мои группы" name="My Groups"/>
- <menu_item_check label="Локальный чат" name="Nearby Chat"/>
+ <menu_item_check label="Чат..." name="Nearby Chat"/>
+ <menu_item_check label="Говорить" name="Speak"/>
+ <menu_item_check label="Настройки голоса..." name="Nearby Voice"/>
+ <menu_item_check label="Изменение голоса..." name="ShowVoice"/>
+ <menu_item_check label="Жесты..." name="Gestures"/>
+ <menu_item_call label="Друзья" name="My Friends"/>
+ <menu_item_call label="Группы" name="My Groups"/>
<menu_item_call label="Люди неподалеку" name="Active Speakers"/>
- <menu_item_check label="Голоса собеседников" name="Nearby Voice"/>
</menu>
<menu label="Мир" name="World">
- <menu_item_check label="Миникарта" name="Mini-Map"/>
+ <menu_item_call label="Добавить закладку на это место" name="Create Landmark Here"/>
+ <menu_item_call label="Пункты..." name="Destinations"/>
<menu_item_check label="Карта мира" name="World Map"/>
+ <menu_item_check label="Миникарта" name="Mini-Map"/>
<menu_item_check label="Поиск" name="Search"/>
+ <menu_item_call label="Телепортация домой" name="Teleport Home"/>
+ <menu_item_call label="Установить дом здесь" name="Set Home to Here"/>
<menu_item_call label="Снимок" name="Take Snapshot"/>
- <menu_item_call label="Добавить закладку на это место" name="Create Landmark Here"/>
- <menu label="Профиль места" name="Land">
- <menu_item_call label="Профиль места" name="Place Profile"/>
- <menu_item_call label="О земле" name="About Land"/>
- <menu_item_call label="Регион/землевладение" name="Region/Estate"/>
- </menu>
+ <menu_item_call label="Профиль места" name="Place Profile"/>
+ <menu_item_call label="О земле" name="About Land"/>
+ <menu_item_call label="Регион/землевладение" name="Region/Estate"/>
+ <menu_item_call label="Мои владения..." name="My Land"/>
<menu_item_call label="Купить эту землю" name="Buy Land"/>
- <menu_item_call label="Моя земля" name="My Land"/>
<menu label="Показать" name="LandShow">
- <menu_item_check label="Панель движения" name="Movement Controls"/>
- <menu_item_check label="Панель камеры" name="Camera Controls"/>
<menu_item_check label="Линии запрета" name="Ban Lines"/>
<menu_item_check label="Метки" name="beacons"/>
<menu_item_check label="Границы собственности" name="Property Lines"/>
@@ -56,16 +61,15 @@
<menu_item_check label="Свойства участка" name="Parcel Properties"/>
<menu_item_check label="Меню «Дополнительно»" name="Show Advanced Menu"/>
</menu>
- <menu_item_call label="Телепортироваться домой" name="Teleport Home"/>
- <menu_item_call label="Установить дом здесь" name="Set Home to Here"/>
<menu label="Солнце" name="Environment Settings">
<menu_item_call label="Восход" name="Sunrise"/>
<menu_item_call label="Полдень" name="Noon"/>
<menu_item_call label="Закат" name="Sunset"/>
<menu_item_call label="Полночь" name="Midnight"/>
+ <menu_item_call label="Использовать настройки региона" name="Use Region Settings"/>
</menu>
- <menu label="Редактор среды" name="Enviroment Editor">
- <menu_item_call label="Настройки среды..." name="Enviroment Settings"/>
+ <menu label="Редактор среды" name="Environment Editor">
+ <menu_item_call label="Настройки среды..." name="Environment Settings"/>
<menu label="Настройки воды" name="Water Presets">
<menu_item_call label="Создать настройку..." name="new_water_preset"/>
<menu_item_call label="Изменить настройку..." name="edit_water_preset"/>
@@ -144,6 +148,7 @@
<menu_item_call label="Вернуть" name="Redo"/>
</menu>
<menu label="Справка" name="Help">
+ <menu_item_call label="Инструкции..." name="How To"/>
<menu_item_call label="Справка по [SECOND_LIFE]" name="Second Life Help"/>
<menu_item_call label="Жалоба" name="Report Abuse"/>
<menu_item_call label="Сообщить об ошибке" name="Report Bug"/>
@@ -198,11 +203,10 @@
<menu_item_check label="Использовать поток для чтения подключаемых модулей" name="Use Plugin Read Thread"/>
<menu_item_call label="Очистить кэш группы" name="ClearGroupCache"/>
<menu_item_check label="Сглаживание мышью" name="Mouse Smoothing"/>
+ <menu_item_call label="Освободить клавиши" name="Release Keys"/>
<menu label="Горячие клавиши" name="Shortcuts">
<menu_item_call label="Изображение (L$[COST])..." name="Upload Image"/>
<menu_item_check label="Поиск" name="Search"/>
- <menu_item_call label="Освободить клавиши" name="Release Keys"/>
- <menu_item_call label="Сбросить размер интерфейса" name="Set UI Size to Default"/>
<menu_item_check label="Показать меню «Дополнительно» - старое сочетание клавиш" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="Закрыть окно" name="Close Window"/>
<menu_item_call label="Закрыть все окна" name="Close All Windows"/>
@@ -288,6 +292,7 @@
<menu_item_check label="Освещение" name="Lights"/>
<menu_item_check label="Каркас столкновений" name="Collision Skeleton"/>
<menu_item_check label="Лучи" name="Raycast"/>
+ <menu_item_check label="Направления ветра" name="Wind Vectors"/>
<menu_item_check label="Сложность визуализации" name="rendercomplexity"/>
<menu_item_check label="Лепка" name="Sculpt"/>
</menu>
@@ -300,7 +305,6 @@
<menu_item_check label="Освещение и тени" name="Lighting and Shadows"/>
<menu_item_check label="Тени от солнца, луны и прожекторов" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO и сглаживание теней" name="SSAO and Shadow Smoothing"/>
- <menu_item_check label="Повсеместное освещение (экспериментальное)" name="Global Illumination"/>
<menu_item_check label="Отладка GL" name="Debug GL"/>
<menu_item_check label="Отладка конвейера" name="Debug Pipeline"/>
<menu_item_check label="Автоматические альфа-маски (отложенные)" name="Automatic Alpha Masks (deferred)"/>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index 1be14160ed..04f2f6b486 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -1110,8 +1110,13 @@
<notification name="DisplaySetToSafe">
Установлен безопасный уровень настроек отображения, так как указан параметр -safe.
</notification>
- <notification name="DisplaySetToRecommended">
- Установлен рекомендуемый уровень настроек отображения в соответствии с вашей системной конфигурацией.
+ <notification name="DisplaySetToRecommendedGPUChange">
+ Установлен рекомендуемый уровень настроек отображения, так как графическая карта изменена:
+с «[LAST_GPU]»
+на «[THIS_GPU]»
+ </notification>
+ <notification name="DisplaySetToRecommendedFeatureChange">
+ Установлен рекомендуемый уровень настроек отображения, так как подсистема визуализации изменена.
</notification>
<notification name="ErrorMessage">
[ERROR_MESSAGE]
@@ -1431,7 +1436,7 @@ http://secondlife.com/download.
<usetemplate ignoretext="Подтверждать перед возвратом объектов владельцам" name="okcancelignore" notext="Отмена" yestext="OK"/>
</notification>
<notification name="GroupLeaveConfirmMember">
- Вы являетесь участником группы [GROUP].
+ Вы являетесь участником группы &lt;nolink&gt;[GROUP]&lt;/nolink&gt;.
Хотите покинуть группу?
<usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
</notification>
@@ -1910,7 +1915,13 @@ http://secondlife.com/download.
<usetemplate ignoretext="Подтверждать перед выходом" name="okcancelignore" notext="Не выходить" yestext="Выйти"/>
</notification>
<notification name="ConfirmRestoreToybox">
- Вы действительно хотите восстановить принятые по умолчанию кнопки и панели инструментов?
+ Это действие приведет к восстановлению стандартных кнопок и панелей инструментов.
+
+Это действие нельзя отменить.
+ <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
+ </notification>
+ <notification name="ConfirmClearAllToybox">
+ Это действие возвращает все кнопки в инструментарий, а панели инструментов становятся пустыми.
Это действие нельзя отменить.
<usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
@@ -2236,14 +2247,16 @@ http://secondlife.com/download.
Ваша визитка отклонена.
</notification>
<notification name="TeleportToLandmark">
- Вы можете телепортироваться в такие места, как «[NAME]», открыв панель «Места» в правой части экрана и выбрав вкладку «Закладки».
-Щелкните любую закладку, чтобы выбрать ее, а затем нажмите кнопку «Телепортация» внизу панели.
-(Также можно дважды щелкнуть закладку или щелкнуть ее правой кнопкой мыши и выбрать команду «Телепортация».)
+ Для телепортации в другое место, например «[NAME]», нажмите кнопку «Места»,
+ затем в открывшемся окне выберите вкладку «Закладки». Щелкните любую
+ закладку, чтобы выбрать ее, а затем нажмите кнопку «Телепортация» внизу окна.
+ (Также можно дважды щелкнуть закладку или щелкнуть ее правой кнопкой мыши и
+ выбрать команду «Телепортация».)
</notification>
<notification name="TeleportToPerson">
- Вы можете общаться с такими жителями, как «[NAME]», открыв панель «Люди» в правой части экрана.
-Выберите в списке нужного жителя, а затем нажмите кнопку «IM» внизу панели.
-(Также можно дважды щелкнуть имя жителя в списке или щелкнуть ее правой кнопкой мыши и выбрать команду «IM».)
+ Чтобы обратиться к жителю, например «[NAME]», нажмите кнопку «Люди», выберите жителя в появившемся окне и нажмите кнопку
+ «IM» внизу окна.
+ (Также можно дважды щелкнуть имя жителя в списке или щелкнуть его правой кнопкой мыши и выбрать команду «IM».)
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Нельзя выбрать землю с обеих сторон границы между серверами.
@@ -2264,6 +2277,9 @@ http://secondlife.com/download.
<notification name="PaymentSent">
[MESSAGE]
</notification>
+ <notification name="PaymentFailure">
+ [MESSAGE]
+ </notification>
<notification name="EventNotification">
Уведомление о событии:
@@ -2798,7 +2814,7 @@ http://secondlife.com/download.
Со следующими жителями:
[RESIDENTS]
- <usetemplate name="okcancelbuttons" notext="Отмена" yestext="ОК"/>
+ <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
</notification>
<notification name="ItemsShared">
Предметы успешно розданы.
@@ -2888,7 +2904,7 @@ http://secondlife.com/download.
позже, даже после того, как вы покинули разговор.
Заглушить всех?
- <usetemplate ignoretext="Подтверждать перед заглушением всех участников группового разговора" name="okcancelignore" notext="Отмена" yestext="ОК"/>
+ <usetemplate ignoretext="Подтверждать перед заглушением всех участников группового разговора" name="okcancelignore" notext="Отмена" yestext="OK"/>
</notification>
<notification label="Чат" name="HintChat">
Чтобы присоединиться к чату, введите слова в поле чата ниже.
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_skin.xml b/indra/newview/skins/default/xui/ru/panel_edit_skin.xml
index ac7e74316e..f5a5339afe 100644
--- a/indra/newview/skins/default/xui/ru/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_skin.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skin_panel">
<panel name="avatar_skin_color_panel">
- <texture_picker label="Тату на голове" name="Head Tattoos" tool_tip="Щелкните для выбора изображения"/>
- <texture_picker label="Тату на верхних частях тела" name="Upper Tattoos" tool_tip="Щелкните для выбора изображения"/>
- <texture_picker label="Тату на нижних частях тела" name="Lower Tattoos" tool_tip="Щелкните для выбора изображения"/>
+ <texture_picker label="Голова" name="Head" tool_tip="Щелкните для выбора изображения"/>
+ <texture_picker label="Верхняя часть тела" name="Upper Body" tool_tip="Щелкните для выбора изображения"/>
+ <texture_picker label="Нижняя часть тела" name="Lower Body" tool_tip="Щелкните для выбора изображения"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/ru/panel_nearby_chat.xml b/indra/newview/skins/default/xui/ru/panel_nearby_chat.xml
index 1d26eecf87..8e3aac38d2 100644
--- a/indra/newview/skins/default/xui/ru/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/ru/panel_nearby_chat.xml
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="nearby_chat">
- <check_box label="Перевод чата" name="translate_chat_checkbox"/>
+ <check_box label="Переводить чат" name="translate_chat_checkbox"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_postcard_message.xml b/indra/newview/skins/default/xui/ru/panel_postcard_message.xml
new file mode 100644
index 0000000000..70587d8090
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_postcard_message.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_message">
+ <text name="to_label">
+ Кому:
+ </text>
+ <text name="name_label">
+ От:
+ </text>
+ <text name="subject_label">
+ Тема:
+ </text>
+ <line_editor label="Введите тему письма." name="subject_form"/>
+ <text name="msg_label">
+ Сообщение:
+ </text>
+ <text_editor name="msg_form">
+ Введите текст письма.
+ </text_editor>
+ <button label="Отмена" name="cancel_btn"/>
+ <button label="Послать" name="send_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_postcard_settings.xml b/indra/newview/skins/default/xui/ru/panel_postcard_settings.xml
new file mode 100644
index 0000000000..dc9d59008f
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_postcard_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_settings">
+ <combo_box label="Размер" name="postcard_size_combo">
+ <combo_box.item label="Текущее окно" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Задать" name="Custom"/>
+ </combo_box>
+ <layout_stack name="postcard_image_params_ls">
+ <layout_panel name="postcard_image_size_lp">
+ <spinner label="Ширина" name="postcard_snapshot_width"/>
+ <spinner label="Высота" name="postcard_snapshot_height"/>
+ <check_box label="Сохранять пропорции" name="postcard_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="postcard_image_format_quality_lp">
+ <slider label="Качество изображения" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
index a3ee5b7815..a9d5569c7f 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
@@ -29,29 +29,5 @@
<check_box label="Текстовые чаты" name="EnableIMChatPopups" tool_tip="Отображать всплывающие уведомления при получении IM-сообщений"/>
<spinner label="Время отображения всплывающих реплик:" name="nearby_toasts_lifetime"/>
<spinner label="Время затухания всплывающих реплик:" name="nearby_toasts_fadingtime"/>
- <text name="translate_chb_label">
- Использовать машинный перевод при общении
- </text>
- <text name="translate_language_text">
- Переводить чат на:
- </text>
- <combo_box name="translate_language_combobox">
- <combo_box.item label="Язык системы" name="System Default Language"/>
- <combo_box.item label="English" name="English"/>
- <combo_box.item label="Dansk" name="Danish"/>
- <combo_box.item label="Deutsch" name="German"/>
- <combo_box.item label="Español" name="Spanish"/>
- <combo_box.item label="Français" name="French"/>
- <combo_box.item label="Italiano" name="Italian"/>
- <combo_box.item label="Magyar" name="Hungarian"/>
- <combo_box.item label="Nederlands" name="Dutch"/>
- <combo_box.item label="Polski" name="Polish"/>
- <combo_box.item label="Português" name="Portugese"/>
- <combo_box.item label="Русский" name="Russian"/>
- <combo_box.item label="Türkçe" name="Turkish"/>
- <combo_box.item label="Українська" name="Ukrainian"/>
- <combo_box.item label="中文 (简体) (китайский)" name="Chinese"/>
- <combo_box.item label="日本語 (Japanese)" name="Japanese"/>
- <combo_box.item label="한국어 (Korean)" name="Korean"/>
- </combo_box>
+ <button label="Настройки перевода чата" name="ok_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_general.xml b/indra/newview/skins/default/xui/ru/panel_preferences_general.xml
index 49f743a6ba..d1bfedf2d8 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_general.xml
@@ -16,7 +16,7 @@
<combo_box.item label="Русский (бета-версия)" name="Russian"/>
<combo_box.item label="Türkçe - турецкий (бета-версия)" name="Turkish"/>
<combo_box.item label="日本語 – японский (бета-версия)" name="(Japanese)"/>
- <combo_box.item label="正體中文 - китайский, традиционное письмо (бета-версия)" name="Traditional Chinese"/>
+ <combo_box.item label="китайский, традиционное письмо - бета-версия" name="Traditional Chinese"/>
</combo_box>
<text name="language_textbox2">
(Требуется перезапуск)
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
index db88189169..8e7fc71f0d 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
@@ -15,7 +15,7 @@
Браузер:
</text>
<radio_group name="use_external_browser">
- <radio_item label="Использовать мой браузер (IE, Firefox, Safari)" name="external" tool_tip="Будет использоваться браузер, заданный в системе по умолчанию. Не рекомендуется, если [APP_NAME] работает в полноэкранном режиме." value="1"/>
+ <radio_item label="Использовать мой браузер (IE, Firefox, Safari)" name="external" tool_tip="Будет использоваться браузер, заданный в системе по умолчанию. Не рекомендуется, если [APP_NAME] работает в полноэкранном режиме." value="true"/>
<radio_item label="Использовать встроенный браузер" name="internal" tool_tip="Для просмотра справки, ссылок на веб-страницы и т. д. будет использоваться встроенный браузер. Этот браузер открывается как новое окно в [APP_NAME]." value=""/>
</radio_group>
<check_box initial_value="истина" label="Разрешить плагины" name="browser_plugins_enabled"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml
new file mode 100644
index 0000000000..53a150c9f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_inventory">
+ <text name="title">
+ Сохранить в моем инвентаре
+ </text>
+ <text name="hint_lbl">
+ Сохранение изображения в инвентаре стоит L$[UPLOAD_COST]. Чтобы сохранить его как текстуру, выберите один из квадратных форматов.
+ </text>
+ <combo_box label="Размер" name="texture_size_combo">
+ <combo_box.item label="Текущее окно" name="CurrentWindow"/>
+ <combo_box.item label="Маленький (128x128)" name="Small(128x128)"/>
+ <combo_box.item label="Средний (256x256)" name="Medium(256x256)"/>
+ <combo_box.item label="Большой (512x512)" name="Large(512x512)"/>
+ <combo_box.item label="Задать" name="Custom"/>
+ </combo_box>
+ <spinner label="Ширина" name="inventory_snapshot_width"/>
+ <spinner label="Высота" name="inventory_snapshot_height"/>
+ <check_box label="Сохранять пропорции" name="inventory_keep_aspect_check"/>
+ <button label="Отмена" name="cancel_btn"/>
+ <button label="Сохранить" name="save_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_local.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_local.xml
new file mode 100644
index 0000000000..446b9bb2fd
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_snapshot_local.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_local">
+ <text name="title">
+ Сохранить на моем компьютере
+ </text>
+ <combo_box label="Размер" name="local_size_combo">
+ <combo_box.item label="Текущее окно" name="CurrentWindow"/>
+ <combo_box.item label="320x240" name="320x240"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="1280x1024" name="1280x1024"/>
+ <combo_box.item label="1600x1200" name="1600x1200"/>
+ <combo_box.item label="Задать" name="Custom"/>
+ </combo_box>
+ <layout_stack name="local_image_params_ls">
+ <layout_panel name="local_image_size_lp">
+ <spinner label="Ширина" name="local_snapshot_width"/>
+ <spinner label="Высота" name="local_snapshot_height"/>
+ <check_box label="Сохранять пропорции" name="local_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="local_image_format_quality_lp">
+ <combo_box label="Формат" name="local_format_combo">
+ <combo_box.item label="PNG (без потерь)" name="PNG"/>
+ <combo_box.item label="JPEG" name="JPEG"/>
+ <combo_box.item label="BMP (без потерь)" name="BMP"/>
+ </combo_box>
+ <slider label="Качество изображения" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <button label="Отмена" name="cancel_btn"/>
+ <flyout_button label="Сохранить" name="save_btn" tool_tip="Сохранить изображение в файл">
+ <flyout_button.item label="Сохранить" name="save_item"/>
+ <flyout_button.item label="Сохранить как..." name="saveas_item"/>
+ </flyout_button>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml
new file mode 100644
index 0000000000..250a76cd21
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_options">
+ <button label="Поместить в мой профиль" name="save_to_profile_btn"/>
+ <button label="Отправить по почте" name="save_to_email_btn"/>
+ <button label="Сохранить в моем инвентаре (L$[AMOUNT])" name="save_to_inventory_btn"/>
+ <button label="Сохранить на моем компьютере" name="save_to_computer_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml
new file mode 100644
index 0000000000..47f4caf8e3
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_postcard">
+ <string name="default_subject">
+ Открытка из [SECOND_LIFE].
+ </string>
+ <string name="default_message">
+ Побывай здесь!
+ </string>
+ <string name="upload_message">
+ Отправка...
+ </string>
+ <text name="title">
+ Электронное письмо
+ </text>
+ <button label="Сообщение" name="message_btn"/>
+ <button label="Настройки" name="settings_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_profile.xml
new file mode 100644
index 0000000000..79a9ef58d0
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_snapshot_profile.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_profile">
+ <text name="title">
+ Поместить в мой профиль
+ </text>
+ <combo_box label="Размер" name="profile_size_combo">
+ <combo_box.item label="Текущее окно" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Задать" name="Custom"/>
+ </combo_box>
+ <layout_stack name="profile_image_params_ls">
+ <layout_panel name="profile_image_size_lp">
+ <spinner label="Ширина" name="profile_snapshot_width"/>
+ <spinner label="Высота" name="profile_snapshot_height"/>
+ <check_box label="Сохранять пропорции" name="profile_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="profile_image_metadata_lp">
+ <text name="caption_label">
+ Подпись:
+ </text>
+ <check_box initial_value="true" label="Включить расположение" name="add_location_cb"/>
+ </layout_panel>
+ </layout_stack>
+ <button label="Отмена" name="cancel_btn"/>
+ <button label="Опубликовать" name="post_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_status_bar.xml b/indra/newview/skins/default/xui/ru/panel_status_bar.xml
index 6822244196..babe5811ac 100644
--- a/indra/newview/skins/default/xui/ru/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_status_bar.xml
@@ -18,7 +18,7 @@
<panel name="balance_bg">
<text name="balance" tool_tip="Щелкните для обновления вашего баланса L$" value="L$20"/>
<button label="Купить L$" name="buyL" tool_tip="Щелкните для покупки L$"/>
- <button label="Торговый центр" name="goShop" tool_tip="Открыть торговый центр Second Life"/>
+ <button label="Торговый центр" name="goShop" tool_tip="Открыть торговый центр Second Life" width="121"/>
</panel>
<text name="TimeText" tool_tip="Текущее время (тихоокеанское)">
00:00 (тихоокеанское время)
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 7fef5797a9..6d954139ff 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -1211,7 +1211,7 @@ support@secondlife.com.
В вашем инвентаре нет копии этой текстуры
</string>
<string name="InventoryInboxNoItems">
- Покупки из торгового центра будут доставлены сюда.
+ Если вы купите или как-то иначе получите предмет, он появится здесь. Его можно будет перетащить в папку вашего инвентаря или удалить, если он больше не нужен.
</string>
<string name="MarketplaceURL">
http://marketplace.[DOMAIN_NAME]
@@ -1409,6 +1409,9 @@ support@secondlife.com.
<string name="no_attachments">
Нет прикрепленных объектов
</string>
+ <string name="Attachments remain">
+ Присоединения (осталось гнезд: [COUNT])
+ </string>
<string name="Buy">
Купить
</string>
@@ -1535,6 +1538,12 @@ support@secondlife.com.
<string name="Right Pec">
Правая грудь
</string>
+ <string name="Neck">
+ Шея
+ </string>
+ <string name="Avatar Center">
+ Центр аватара
+ </string>
<string name="Invalid Attachment">
Неверная точка присоединения
</string>
@@ -4024,6 +4033,18 @@ support@secondlife.com.
<string name="you_paid_ldollars_no_name">
Вы заплатили L$[AMOUNT] за [REASON].
</string>
+ <string name="you_paid_failure_ldollars">
+ Вы не смогли заплатить пользователю [NAME] L$[AMOUNT]: [REASON].
+ </string>
+ <string name="you_paid_failure_ldollars_no_info">
+ Вы не смогли заплатить L$[AMOUNT]
+ </string>
+ <string name="you_paid_failure_ldollars_no_reason">
+ Вы не смогли заплатить пользователю [NAME] L$[AMOUNT]
+ </string>
+ <string name="you_paid_failure_ldollars_no_name">
+ Вы не смогли заплатить L$[AMOUNT]: [REASON].
+ </string>
<string name="for item">
за [ITEM]
</string>
@@ -4433,6 +4454,12 @@ support@secondlife.com.
<string name="ExternalEditorFailedToRun">
Не удалось запустить внешний редактор.
</string>
+ <string name="TranslationFailed">
+ Ошибка телепортации: [REASON]
+ </string>
+ <string name="TranslationResponseParseError">
+ Ошибка при анализе ответа переводчика.
+ </string>
<string name="Esc">
ESC
</string>
@@ -4815,7 +4842,7 @@ support@secondlife.com.
Миникарта
</string>
<string name="Command_Move_Label">
- Переместить
+ Ходьба / бег / полет
</string>
<string name="Command_People_Label">
Люди
@@ -4842,7 +4869,7 @@ support@secondlife.com.
Говорить
</string>
<string name="Command_View_Label">
- Вид
+ Управление камерой
</string>
<string name="Command_Voice_Label">
Настройки голоса
@@ -4917,7 +4944,16 @@ support@secondlife.com.
Изменение угла камеры
</string>
<string name="Command_Voice_Tooltip">
- Громкость звонков и голосов окружающих вас людей
+ Регулировка громкости вызовов и разговоров с людьми около вас
+ </string>
+ <string name="Toolbar_Bottom_Tooltip">
+ сейчас на нижней панели инструментов
+ </string>
+ <string name="Toolbar_Left_Tooltip">
+ сейчас на левой панели инструментов
+ </string>
+ <string name="Toolbar_Right_Tooltip">
+ сейчас на правой панели инструментов
</string>
<string name="Retain%">
Остаток%
@@ -4943,4 +4979,19 @@ support@secondlife.com.
<string name="Normal">
Нормальный
</string>
+ <string name="snapshot_quality_very_low">
+ Очень низкий
+ </string>
+ <string name="snapshot_quality_low">
+ Низкий
+ </string>
+ <string name="snapshot_quality_medium">
+ Средний
+ </string>
+ <string name="snapshot_quality_high">
+ Высокий
+ </string>
+ <string name="snapshot_quality_very_high">
+ Очень высокий
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/ru/teleport_strings.xml b/indra/newview/skins/default/xui/ru/teleport_strings.xml
index 296562e6f1..feff286111 100644
--- a/indra/newview/skins/default/xui/ru/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/ru/teleport_strings.xml
@@ -21,8 +21,8 @@
Повторите попытку позже.
</message>
<message name="NoHelpIslandTP">
- Вы не можете телепортироваться обратно на Остров Помощи.
-Телепортируйтесь на Общественный Остров Помощи, чтобы повторить обучение
+ Телепортироваться назад на Остров прибытия нельзя.
+Для повторения учебника перейдите на «Остров прибытия - общий».
</message>
<message name="noaccess_tport">
У вас нет доступа к точке назначения этого телепорта.
diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml
index 993ec42958..8fa12ea759 100644
--- a/indra/newview/skins/default/xui/tr/floater_about.xml
+++ b/indra/newview/skins/default/xui/tr/floater_about.xml
@@ -64,32 +64,34 @@ Ses Sunucusu Sürümü: [VOICE_VERSION]
<panel label="Lisanslar" name="licenses_panel">
<text_editor name="credits_editor">
3Dconnexion SDK Telif Hakkı (C) 1992-2007 3Dconnexion
-APR Telif Hakkı (C) 2000-2004 The Apache Software Foundation
-Collada DOM Telif Hakkı 2005 Sony Computer Entertainment Inc.
-cURL Telif Hakkı (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
-DBus/dbus-glib Telif Hakkı (C) 2002, 2003 CodeFactory AB / Telif Hakkı (C) 2003, 2004 Red Hat, Inc.
-expat Telif Hakkı (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
-FreeType Telif Hakkı (C) 1996-2002, The FreeType Project (www.freetype.org).
-GL Telif Hakkı (C) 1999-2004 Brian Paul.
-GLOD Telif Hakkı (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University ve David Luebke, Brenden Schubert, University of Virginia.
-google-perftools Telif Hakkı (c) 2005, Google Inc.
-Havok.com(TM) Telif Hakkı (C) 1999-2001, Telekinesys Research Limited.
-jpeg2000 Telif Hakkı (C) 2001, David Taubman, The University of New South Wales (UNSW)
-jpeglib Telif Hakkı (C) 1991-1998, Thomas G. Lane.
-ogg/vorbis Telif Hakkı (C) 2001, Xiphophorus
-OpenSSL Telif Hakkı (C) 1998-2002 The OpenSSL Project.
-PCRE Telif Hakkı (c) 1997-2008 University of Cambridge
-SDL Telif Hakkı (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
-SSLeay Telif Hakkı (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-xmlrpc-epi Telif Hakkı (C) 2000 Epinions, Inc.
-zlib Telif Hakkı (C) 1995-2002 Jean-loup Gailly ve Mark Adler.
-google-perftools Telif Hakkı (c) 2005, Google Inc.
+ APR Telif Hakkı (C) 2000-2004 The Apache Software Foundation
+ Collada DOM Telif Hakkı 2005 Sony Computer Entertainment Inc.
+ cURL Telif Hakkı (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ DBus/dbus-glib Telif Hakkı (C) 2002, 2003 CodeFactory AB / Telif Hakkı (C) 2003, 2004 Red Hat, Inc.
+ expat Telif Hakkı (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+ FreeType Telif Hakkı (C) 1996-2002, The FreeType Project (www.freetype.org).
+ GL Telif Hakkı (C) 1999-2004 Brian Paul.
+ GLOD Telif Hakkı (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University ve David Luebke, Brenden Schubert, University of Virginia.
+ google-perftools Telif Hakkı (c) 2005, Google Inc.
+ Havok.com(TM) Telif Hakkı (C) 1999-2001, Telekinesys Research Limited.
+ jpeg2000 Telif Hakkı (C) 2001, David Taubman, The University of New South Wales (UNSW)
+ jpeglib Telif Hakkı (C) 1991-1998, Thomas G. Lane.
+ ogg/vorbis Telif Hakkı (C) 2001, Xiphophorus
+ OpenSSL Telif Hakkı (C) 1998-2002 The OpenSSL Project.
+ PCRE Telif Hakkı (c) 1997-2008 University of Cambridge
+ SDL Telif Hakkı (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+ SSLeay Telif Hakkı (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ xmlrpc-epi Telif Hakkı (C) 2000 Epinions, Inc.
+ zlib Telif Hakkı (C) 1995-2002 Jean-loup Gailly ve Mark Adler.
+ google-perftools Telif Hakkı (c) 2005, Google Inc.
-Second Life Görüntüleyicisi Havok (TM) Fizik motorunu kullanmaktadır. (c)Telif Hakkı 1999-2010 Havok.com Inc. (ve Lisans Verenleri). Tüm Hakları Saklıdır. Ayrıntılı bilgi için bkz. www.havok.com
+ Second Life Görüntüleyicisi Havok (TM) Fizik motorunu kullanmaktadır. (c)Telif Hakkı 1999-2010 Havok.com Inc. (ve Lisans Verenleri). Tüm Hakları Saklıdır. Ayrıntılı bilgi için bkz. www.havok.com
-Tüm hakları saklıdır. Ayrıntılı bilgi için bkz. licenses.txt
+ Bu yazılımda NVIDIA Corporation tarafından sağlanan kaynak kod yer almaktadır.
-Sesli sohbet için Ses kodlaması: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
+ Tüm hakları saklıdır. Ayrıntılı bilgi için bkz. licenses.txt
+
+ Sesli sohbet için Ses kodlaması: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
</text_editor>
</panel>
</tab_container>
diff --git a/indra/newview/skins/default/xui/tr/floater_about_land.xml b/indra/newview/skins/default/xui/tr/floater_about_land.xml
index e0350964b5..dde658d64d 100644
--- a/indra/newview/skins/default/xui/tr/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/tr/floater_about_land.xml
@@ -129,7 +129,7 @@
Trafik:
</text>
<text name="DwellText">
- 0
+ Yükleniyor...
</text>
<button label="Arazi Satın Al" name="Buy Land..."/>
<button label="Linden Satışı" name="Linden Sale..." tool_tip="Arazinin sahip olunması, içeriğinin ayarlanması ve ihaleye çıkmamış olması gerekir"/>
@@ -307,13 +307,15 @@ Sadece büyük parseller aramada görünür.
İtme Yok (Bölge Geçersiz Kılma)
</panel.string>
<panel.string name="see_avs_text">
- Parseldeki sakinleri gör ve onlarla sohbet et
+ Diğer parsellerdeki avatarlar bu
</panel.string>
<text name="allow_label">
Sakinlere şunun için izin ver:
</text>
- <check_box label="Yüzeyi Düzenle" name="edit land check" tool_tip="İşaretliyse herkes arazinizi şekillendirebilir. en iyisi bunu işaretlememektir, çünkü kendi arazinizi her zaman düzenleyebilirsiniz."/>
- <check_box label="Uç" name="check fly" tool_tip="İşaretliyse Sakinler arazinizden uçabilir. İşaretli değilse, sadece arazinize ve arazinizin üzerinde uçabilir."/>
+ <text name="allow_label0">
+ Uçma:
+ </text>
+ <check_box label="Herkes" name="check fly" tool_tip="İşaretliyse Sakinler arazinizden uçabilir. İşaretli değilse, sadece arazinize ve arazinizin üzerinde uçabilir."/>
<text name="allow_label2">
İnşa Et:
</text>
@@ -329,9 +331,6 @@ Sadece büyük parseller aramada görünür.
</text>
<check_box label="Herkes" name="check other scripts"/>
<check_box label="Grup" name="check group scripts"/>
- <text name="land_options_label">
- Arazi Seçenekleri:
- </text>
<check_box label="Güvenli (hasar yok)" name="check safe" tool_tip="İşaretliyse, araziyi Güvenli moda getirerek hasar çarpışmasını etkinsizleştirir İşaretli değilse hasar çarpışması etkinleşir."/>
<check_box label="İtme Yok" name="PushRestrictCheck" tool_tip="Komut dosyalarının itmesini önler Bu seçeneğin işaretlenmesi arazinizdeki bozucu davranışları önlemeye yardımcı olabilir."/>
<check_box label="Konumu Arama sonuçlarında göster (L$30/hafta)" name="ShowDirectoryCheck" tool_tip="Arama sonuçlarında bu parsel görünsün"/>
@@ -372,9 +371,9 @@ Sadece büyük parseller aramada görünür.
</text>
<texture_picker name="snapshot_ctrl" tool_tip="Bir resim seçmek için tıklayın"/>
<text name="allow_label5">
- Diğer parsel Sakinlerine şunun için izin verin:
+ bu parseldeki avatarları görebilir ve onlarla sohbet edebilir
</text>
- <check_box label="Avatarları Gör" name="SeeAvatarsCheck" tool_tip="Diğer parsellerdeki sakinlerin bu parseldeki sakinleri görmesine ve onlarla sohbet etmesine, sizin de onları görüp, onlarla sohbet etmenize imkan tanır."/>
+ <check_box label="Avatarları Gör" name="SeeAvatarsCheck" tool_tip="Diğer parsellerdeki avatarların bu parseldeki avatarları görmesine ve onlarla sohbet etmesine, sizin de onları görüp, onlarla sohbet etmenize imkan tanır."/>
<text name="landing_point">
İniş Noktası: [LANDING]
</text>
diff --git a/indra/newview/skins/default/xui/tr/floater_avatar.xml b/indra/newview/skins/default/xui/tr/floater_avatar.xml
index fc9e3c8a9b..c6b14ba710 100644
--- a/indra/newview/skins/default/xui/tr/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/tr/floater_avatar.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Avatar" title="AVATAR SEÇİCİ"/>
+<floater name="Avatar" title="BİR AVATAR SEÇİN"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_buy_currency.xml b/indra/newview/skins/default/xui/tr/floater_buy_currency.xml
index 6608fd72e1..d90985dcff 100644
--- a/indra/newview/skins/default/xui/tr/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/tr/floater_buy_currency.xml
@@ -46,7 +46,7 @@
L$ [AMT]
</text>
<text name="currency_links">
- [http://www.secondlife.com/my/account/payment_method_management.php ödeme yöntemi] | [http://www.secondlife.com/my/account/currency.php para birimi
+ [http://www.secondlife.com/my/account/payment_method_management.php ödeme yöntemi] | [http://www.secondlife.com/my/account/currency.php para birimi]
</text>
<text name="exchange_rate_note">
En son döviz kurunu görmek için miktarı yeniden girin.
diff --git a/indra/newview/skins/default/xui/tr/floater_camera.xml b/indra/newview/skins/default/xui/tr/floater_camera.xml
index c92d4e9db4..22e2aa52c6 100644
--- a/indra/newview/skins/default/xui/tr/floater_camera.xml
+++ b/indra/newview/skins/default/xui/tr/floater_camera.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="camera_floater" title="GÖSTER">
+<floater name="camera_floater" title="KAMERA DENETİMLERİ">
<floater.string name="rotate_tooltip">
Odak Etrafında Kamerayı Döndür
</floater.string>
diff --git a/indra/newview/skins/default/xui/tr/floater_chat_bar.xml b/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
index d2385e6be3..dee17b7bc4 100644
--- a/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="chat_bar" title="YAKINDAKİ SOHBET">
- <panel>
+ <panel name="bottom_panel">
<line_editor label="Sohbet etmek için buraya tıklayın." name="chat_box" tool_tip="Söylemek için Enter, bağırmak için Ctrl+Enter yapın"/>
<button name="show_nearby_chat" tool_tip="yakın sohbet günlüğünü gösterir/gizler"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/floater_hardware_settings.xml b/indra/newview/skins/default/xui/tr/floater_hardware_settings.xml
index 12927dcaeb..8e056b9b0d 100644
--- a/indra/newview/skins/default/xui/tr/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/tr/floater_hardware_settings.xml
@@ -4,8 +4,8 @@
Filtreleme:
</text>
<check_box label="Anisotropik Filtreleme (etkinken daha yavaş)" name="ani"/>
- <text name="Antialiasing:">
- Antialiasing:
+ <text name="antialiasing label">
+ Düzgünleştirme:
</text>
<combo_box label="Antialiasing" name="fsaa">
<combo_box.item label="Devre dışı" name="FSAADisabled"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_model_preview.xml b/indra/newview/skins/default/xui/tr/floater_model_preview.xml
index 339545f96e..0c7cabc6ea 100644
--- a/indra/newview/skins/default/xui/tr/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/tr/floater_model_preview.xml
@@ -4,6 +4,9 @@
<string name="status_parse_error">
Hata: Tarih ayrıştırma sorunu - ayrıntılar için günlüğe bakın.
</string>
+ <string name="status_material_mismatch">
+ Hata: Modelin malzemesi, referans modelin bir alt kümesi değil.
+ </string>
<string name="status_reading_file">
Yükleniyor...
</string>
diff --git a/indra/newview/skins/default/xui/tr/floater_model_wizard.xml b/indra/newview/skins/default/xui/tr/floater_model_wizard.xml
index 108d20cfac..b3c72ba2da 100644
--- a/indra/newview/skins/default/xui/tr/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/tr/floater_model_wizard.xml
@@ -20,6 +20,9 @@
Karşıya yüklenecek model dosyasını seçin
</text>
<button label="Gözat..." label_selected="Gözat..." name="browse"/>
+ <text name="Model types">
+ Second Life, COLLADA (.dae) dosyalarını destekler
+ </text>
<text name="dimensions">
X Y Z
</text>
diff --git a/indra/newview/skins/default/xui/tr/floater_moveview.xml b/indra/newview/skins/default/xui/tr/floater_moveview.xml
index 74ed613a62..9226218a24 100644
--- a/indra/newview/skins/default/xui/tr/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/tr/floater_moveview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="move_floater" title="HAREKET ET">
+<floater name="move_floater" title="YÜRÜ / KOŞ / UÇ">
<string name="walk_forward_tooltip">
İleri Yürü (Yukarı Okuna veya W&apos;ye basın)
</string>
diff --git a/indra/newview/skins/default/xui/tr/floater_snapshot.xml b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
index 492ec4b588..fa51f15d16 100644
--- a/indra/newview/skins/default/xui/tr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
@@ -3,72 +3,63 @@
<floater.string name="unknown">
bilinmiyor
</floater.string>
- <radio_group label="Anlık görüntü türü" name="snapshot_type_radio">
- <radio_item label="E-posta" name="postcard"/>
- <radio_item label="Envanterim (L$[AMOUNT])" name="texture"/>
- <radio_item label="Bilgisayarıma kaydet" name="local"/>
- </radio_group>
+ <string name="postcard_progress_str">
+ E-posta Gönderiliyor
+ </string>
+ <string name="profile_progress_str">
+ Yayınlanıyor
+ </string>
+ <string name="inventory_progress_str">
+ Envantere Kaydediliyor
+ </string>
+ <string name="local_progress_str">
+ Bilgisayara Kaydediliyor
+ </string>
+ <string name="profile_succeeded_str">
+ Görüntü yüklendi
+ </string>
+ <string name="postcard_succeeded_str">
+ E-posta Gönderildi!
+ </string>
+ <string name="inventory_succeeded_str">
+ Envantere Kaydedildi!
+ </string>
+ <string name="local_succeeded_str">
+ Bilgisayara Kaydedildi!
+ </string>
+ <string name="profile_failed_str">
+ Görüntü Profil Akışınıza yüklenemedi.
+ </string>
+ <string name="postcard_failed_str">
+ E-posta gönderilemedi.
+ </string>
+ <string name="inventory_failed_str">
+ Envantere kaydedilemedi.
+ </string>
+ <string name="local_failed_str">
+ Bilgisayara kaydedilemedi.
+ </string>
+ <button name="advanced_options_btn" tool_tip="Gelişmiş seçenekler"/>
+ <text name="image_res_text">
+ [WIDTH] x [HEIGHT] px
+ </text>
<text name="file_size_label">
[SIZE] KB
</text>
- <button label="Gönder" name="send_btn"/>
- <button label="Kaydet (L$[AMOUNT])" name="upload_btn"/>
- <flyout_button label="Kaydet" name="save_btn" tool_tip="Görüntüyü bir dosyaya kaydet">
- <flyout_button.item label="Kaydet" name="save_item"/>
- <flyout_button.item label="Farklı Kaydet..." name="saveas_item"/>
- </flyout_button>
- <button label="Daha Fazla" name="more_btn" tool_tip="Gelişmiş seçenekler"/>
- <button label="Daha Az" name="less_btn" tool_tip="Gelişmiş seçenekler"/>
- <button label="İptal" name="discard_btn"/>
- <text name="type_label2">
- Büyüklük
- </text>
- <text name="format_label">
- Format
- </text>
- <combo_box label="Çözünürlük" name="postcard_size_combo">
- <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="Özel" name="Custom"/>
- </combo_box>
- <combo_box label="Çözünürlük" name="texture_size_combo">
- <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
- <combo_box.item label="Küçük (128x128)" name="Small(128x128)"/>
- <combo_box.item label="Orta (256x256)" name="Medium(256x256)"/>
- <combo_box.item label="Büyük (512x512)" name="Large(512x512)"/>
- <combo_box.item label="Özel" name="Custom"/>
- </combo_box>
- <combo_box label="Çözünürlük" name="local_size_combo">
- <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
- <combo_box.item label="320x240" name="320x240"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1280x1024" name="1280x1024"/>
- <combo_box.item label="1600x1200" name="1600x1200"/>
- <combo_box.item label="Özel" name="Custom"/>
- </combo_box>
- <combo_box label="Format" name="local_format_combo">
- <combo_box.item label="PNG" name="PNG"/>
- <combo_box.item label="JPEG" name="JPEG"/>
- <combo_box.item label="BMP" name="BMP"/>
- </combo_box>
- <spinner label="Genişlik" name="snapshot_width"/>
- <spinner label="Yükseklik" name="snapshot_height"/>
- <check_box label="Oranları Koru" name="keep_aspect_check"/>
- <slider label="Görüntü kalitesi" name="image_quality_slider"/>
- <text name="layer_type_label">
- Yakala:
- </text>
- <combo_box label="Görüntü Katmanları" name="layer_types">
- <combo_box.item label="Renkler" name="Colors"/>
- <combo_box.item label="Derinlik" name="Depth"/>
- </combo_box>
- <check_box label="Arayüz" name="ui_check"/>
- <check_box label="BÜG&apos;ler" name="hud_check"/>
- <check_box label="Kaydettikten sonra açık tut" name="keep_open_check"/>
- <check_box label="Kare dondur (tam ekran)" name="freeze_frame_check"/>
- <check_box label="Otomatik yenile" name="auto_snapshot_check"/>
+ <panel name="advanced_options_panel">
+ <text name="advanced_options_label">
+ GELİŞMİŞ SEÇENEKLER
+ </text>
+ <text name="layer_type_label">
+ Yakala:
+ </text>
+ <combo_box label="Görüntü Katmanları" name="layer_types">
+ <combo_box.item label="Renkler" name="Colors"/>
+ <combo_box.item label="Derinlik" name="Depth"/>
+ </combo_box>
+ <check_box label="Arayüz" name="ui_check"/>
+ <check_box label="BÜG&apos;ler" name="hud_check"/>
+ <check_box label="Kare dondur (tam ekran)" name="freeze_frame_check"/>
+ <check_box label="Otomatik yenile" name="auto_snapshot_check"/>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_toybox.xml b/indra/newview/skins/default/xui/tr/floater_toybox.xml
index 05d3633df0..e60e176643 100644
--- a/indra/newview/skins/default/xui/tr/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/tr/floater_toybox.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Toybox" title="ARAÇ ÇUBUKLARINI ÖZELLEŞTİR">
+<floater name="Toybox" title="ARAÇ ÇUBUĞU DÜĞMELERİ">
<text name="toybox label 1">
Düğmeleri araç çubuklarına veya araç çubuklarından sürükleyerek ekleyin ya da kaldırın.
</text>
<text name="toybox label 2">
Her bir araç çubuğunun ayarına göre düğmeler gösterilir veya sadece simgeleri yer alır.
</text>
+ <button label="Tüm araç çubuklarını temizle" label_selected="Tüm araç çubuklarını temizle" name="btn_clear_all"/>
<button label="Varsayılanları geri yükle" label_selected="Varsayılanları geri yükle" name="btn_restore_defaults"/>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_translation_settings.xml b/indra/newview/skins/default/xui/tr/floater_translation_settings.xml
new file mode 100644
index 0000000000..33ce76bd9a
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_translation_settings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_translation_settings" title="SOHBET ÇEVİRİSİ AYARLARI">
+ <string name="bing_api_key_not_verified">
+ Bing uygulama kimliği doğrulanmadı. Lütfen tekrar deneyin.
+ </string>
+ <string name="google_api_key_not_verified">
+ Google API anahtarı doğrulanmadı. Lütfen tekrar deneyin.
+ </string>
+ <string name="bing_api_key_verified">
+ Bing uygulama kimliği doğrulandı.
+ </string>
+ <string name="google_api_key_verified">
+ Google API anahtarı doğrulandı.
+ </string>
+ <check_box label="Sohbet ederken makine çevirisini etkinleştirin" name="translate_chat_checkbox"/>
+ <text name="translate_language_label">
+ Sohbeti şu dile çevir:
+ </text>
+ <combo_box name="translate_language_combo">
+ <combo_box.item label="Sistem Varsayılanı" name="System Default Language"/>
+ <combo_box.item label="İngilizce" name="English"/>
+ <combo_box.item label="Dansk (Danca)" name="Danish"/>
+ <combo_box.item label="Deutsch (Almanca)" name="German"/>
+ <combo_box.item label="Español (İspanyolca)" name="Spanish"/>
+ <combo_box.item label="Français (Fransızca)" name="French"/>
+ <combo_box.item label="Italiano (İtalyanca)" name="Italian"/>
+ <combo_box.item label="Magyar (Macarca)" name="Hungarian"/>
+ <combo_box.item label="Nederlands (Flemenkçe)" name="Dutch"/>
+ <combo_box.item label="Polski (Lehçe)" name="Polish"/>
+ <combo_box.item label="Português (Portekizce)" name="Portugese"/>
+ <combo_box.item label="Русский (Rusça)" name="Russian"/>
+ <combo_box.item label="Türkçe (Türkçe)" name="Turkish"/>
+ <combo_box.item label="Українська (Ukraynaca)" name="Ukrainian"/>
+ <combo_box.item label="中文 (正體) (Çince)" name="Chinese"/>
+ <combo_box.item label="日本語 (Japonca)" name="Japanese"/>
+ <combo_box.item label="한국어 (Korece)" name="Korean"/>
+ </combo_box>
+ <text name="tip">
+ Çeviri hizmetini seçin:
+ </text>
+ <radio_group name="translation_service_rg">
+ <radio_item initial_value="bing" label="Bing Çevirmeni" name="bing"/>
+ <radio_item initial_value="google" label="Google Translate" name="google"/>
+ </radio_group>
+ <text name="bing_api_key_label">
+ Bing [http://www.bing.com/developers/createapp.aspx Uygulama Kimliği]:
+ </text>
+ <button label="Doğrula" name="verify_bing_api_key_btn"/>
+ <text name="google_api_key_label">
+ Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API anahtarı]:
+ </text>
+ <button label="Doğrula" name="verify_google_api_key_btn"/>
+ <text name="google_links_text">
+ [http://code.google.com/apis/language/translate/v2/pricing.html Fiyatlandırma] | [https://code.google.com/apis/console İstatistikler]
+ </text>
+ <button label="Tamam" name="ok_btn"/>
+ <button label="İptal" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_voice_controls.xml b/indra/newview/skins/default/xui/tr/floater_voice_controls.xml
index dac05d8327..5ff0804f17 100644
--- a/indra/newview/skins/default/xui/tr/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/tr/floater_voice_controls.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_voice_controls" title="SES DENETİMLERİ">
<string name="title_nearby">
- Yakındaki ses
+ SES AYARLARI
</string>
<string name="title_group">
- [GROUP] ile grup araması
+ [GROUP] İLE GRUP ARAMASI
</string>
<string name="title_adhoc">
- Konferans araması
+ KONFERANS ARAMASI
</string>
<string name="title_peer_2_peer">
- [NAME] ile arama
+ [NAME] İLE ARAMA
</string>
<string name="no_one_near">
Yakındaki kimsede ses etkin değil
diff --git a/indra/newview/skins/default/xui/tr/menu_toolbars.xml b/indra/newview/skins/default/xui/tr/menu_toolbars.xml
index 7cb3192ec4..c8523a6ec9 100644
--- a/indra/newview/skins/default/xui/tr/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/tr/menu_toolbars.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Toolbars Popup">
- <menu_item_call label="Düğmeleri seç..." name="Chose Buttons"/>
+ <menu_item_call label="Bu düğmeyi kaldır" name="Remove button"/>
+ <menu_item_call label="Araç çubuğu düğmeleri..." name="Choose Buttons"/>
<menu_item_check label="Simgeler ve etiketler" name="icons_with_text"/>
<menu_item_check label="Sadece simgeler" name="icons_only"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml
index 75294e38d5..ef10d639d7 100644
--- a/indra/newview/skins/default/xui/tr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml
@@ -1,12 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu_bar name="Main Menu">
<menu label="Ben" name="Me">
- <menu_item_call label="Kontrol Paneli..." name="Manage My Account"/>
<menu_item_call label="Profil..." name="Profile"/>
<menu_item_call label="Görünüm..." name="ChangeOutfit"/>
+ <menu_item_call label="Bir avatar seçin..." name="Avatar Picker"/>
<menu_item_check label="Envanter..." name="Inventory"/>
- <menu_item_check label="Mimikler..." name="Gestures"/>
- <menu_item_check label="Ses..." name="ShowVoice"/>
+ <menu_item_call label="Yeni Envanter Penceresi" name="NewInventoryWindow"/>
+ <menu_item_call label="Yerler..." name="Places"/>
+ <menu_item_call label="Favoriler..." name="Picks"/>
+ <menu_item_call label="Kamera Denetimleri..." name="Camera Controls"/>
<menu label="Hareket" name="Movement">
<menu_item_call label="Otur" name="Sit Down Here"/>
<menu_item_check label="Uç" name="Fly"/>
@@ -20,34 +22,37 @@
<menu_item_call label="Yönetici Durumu Talep Et" name="Request Admin Options"/>
<menu_item_call label="Yönetici Durumundan Ayrıl" name="Leave Admin Options"/>
<menu_item_call label="L$ Satın Al" name="Buy and Sell L$"/>
+ <menu_item_call label="Hesap kontrol paneli..." name="Manage My Account"/>
<menu_item_call label="Tercihler..." name="Preferences"/>
- <menu_item_call label="Araç çubukları..." name="Toolbars"/>
+ <menu_item_call label="Araç çubuğu düğmeleri..." name="Toolbars"/>
<menu_item_call label="Tüm denetimleri sakla" name="Hide UI"/>
<menu_item_call label="[APP_NAME]&apos;den Çık" name="Quit"/>
</menu>
<menu label="İletişim Kur" name="Communicate">
- <menu_item_call label="Arkadaşlarım" name="My Friends"/>
- <menu_item_call label="Gruplarım" name="My Groups"/>
- <menu_item_check label="Yakındaki Sohbet" name="Nearby Chat"/>
- <menu_item_call label="Yakındaki Kişiler" name="Active Speakers"/>
- <menu_item_check label="Yakındaki Ses" name="Nearby Voice"/>
+ <menu_item_check label="Sohbet..." name="Nearby Chat"/>
+ <menu_item_check label="Konuş" name="Speak"/>
+ <menu_item_check label="Ses ayarları..." name="Nearby Voice"/>
+ <menu_item_check label="Ses şekillendirme..." name="ShowVoice"/>
+ <menu_item_check label="Mimikler..." name="Gestures"/>
+ <menu_item_call label="Arkadaşlar" name="My Friends"/>
+ <menu_item_call label="Gruplar" name="My Groups"/>
+ <menu_item_call label="Yakındaki kişiler" name="Active Speakers"/>
</menu>
<menu label="Dünya" name="World">
+ <menu_item_call label="Bu Yeri Yer İmlerine Ekle" name="Create Landmark Here"/>
+ <menu_item_call label="Hedef Konumlar..." name="Destinations"/>
+ <menu_item_check label="Dünya haritası" name="World Map"/>
<menu_item_check label="Mini-harita" name="Mini-Map"/>
- <menu_item_check label="Dünya Haritası" name="World Map"/>
<menu_item_check label="Ara" name="Search"/>
+ <menu_item_call label="Ana konuma ışınlan" name="Teleport Home"/>
+ <menu_item_call label="Ana konumu burası olarak seç" name="Set Home to Here"/>
<menu_item_call label="Anlık Görüntü" name="Take Snapshot"/>
- <menu_item_call label="Bu Yeri Yer İmlerine Ekle" name="Create Landmark Here"/>
- <menu label="Profili Yerleştir" name="Land">
- <menu_item_call label="Profili Yerleştir" name="Place Profile"/>
- <menu_item_call label="Arazi Hakkında" name="About Land"/>
- <menu_item_call label="Bölge/Gayrimenkul" name="Region/Estate"/>
- </menu>
- <menu_item_call label="Bu Araziyi Satın Al" name="Buy Land"/>
- <menu_item_call label="Arazim" name="My Land"/>
+ <menu_item_call label="Profili yerleştir" name="Place Profile"/>
+ <menu_item_call label="Arazi hakkında" name="About Land"/>
+ <menu_item_call label="Bölge / Gayrimenkul" name="Region/Estate"/>
+ <menu_item_call label="Sahip olduğum arazi parçaları..." name="My Land"/>
+ <menu_item_call label="Bu araziyi satın al" name="Buy Land"/>
<menu label="Göster" name="LandShow">
- <menu_item_check label="Denetimleri Hareket Ettir" name="Movement Controls"/>
- <menu_item_check label="Denetimleri Göster" name="Camera Controls"/>
<menu_item_check label="Yasaklama Çizgileri" name="Ban Lines"/>
<menu_item_check label="İşaretler" name="beacons"/>
<menu_item_check label="Mülkiyet Çizgileri" name="Property Lines"/>
@@ -56,16 +61,15 @@
<menu_item_check label="Parsel Özellikleri" name="Parcel Properties"/>
<menu_item_check label="Gelişmiş Menü" name="Show Advanced Menu"/>
</menu>
- <menu_item_call label="Ana Konuma Işınla" name="Teleport Home"/>
- <menu_item_call label="Ana Konumu Burası Olarak Seç" name="Set Home to Here"/>
<menu label="Güneş" name="Environment Settings">
<menu_item_call label="Gün Doğumu" name="Sunrise"/>
<menu_item_call label="Gün Ortası" name="Noon"/>
<menu_item_call label="Gün Batımı" name="Sunset"/>
<menu_item_call label="Gece Yarısı" name="Midnight"/>
+ <menu_item_call label="Bölge Ayarlarını Kullanın" name="Use Region Settings"/>
</menu>
- <menu label="Ortam Düzenleyici" name="Enviroment Editor">
- <menu_item_call label="Ortam Ayarları..." name="Enviroment Settings"/>
+ <menu label="Ortam Düzenleyici" name="Environment Editor">
+ <menu_item_call label="Ortam Ayarları..." name="Environment Settings"/>
<menu label="Su Ön Ayarları" name="Water Presets">
<menu_item_call label="Yeni ön ayar..." name="new_water_preset"/>
<menu_item_call label="Ön ayarı düzenle..." name="edit_water_preset"/>
@@ -144,6 +148,7 @@
<menu_item_call label="Yinele" name="Redo"/>
</menu>
<menu label="Yardım" name="Help">
+ <menu_item_call label="Nasıl yapılır..." name="How To"/>
<menu_item_call label="[SECOND_LIFE] Yardımı" name="Second Life Help"/>
<menu_item_call label="Kötüye Kullanımı Bildir" name="Report Abuse"/>
<menu_item_call label="Hata Bildir" name="Report Bug"/>
@@ -198,11 +203,10 @@
<menu_item_check label="İş Parçacığı Okuma Eklentisini Kullan" name="Use Plugin Read Thread"/>
<menu_item_call label="Grup Ön Belleğini Temizle" name="ClearGroupCache"/>
<menu_item_check label="Fare Düzleştirme" name="Mouse Smoothing"/>
+ <menu_item_call label="Bırakma Anahtarları" name="Release Keys"/>
<menu label="Kısa Yollar" name="Shortcuts">
<menu_item_call label="Görüntü (L$[COST])..." name="Upload Image"/>
<menu_item_check label="Ara" name="Search"/>
- <menu_item_call label="Bırakma Anahtarları" name="Release Keys"/>
- <menu_item_call label="KA Büyüklüğünü Varsayılana Ayarla" name="Set UI Size to Default"/>
<menu_item_check label="Gelişmiş Menüyü Göster - eski kısayol" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="Pencereyi Kapat" name="Close Window"/>
<menu_item_call label="Tüm Pencereleri Kapat" name="Close All Windows"/>
@@ -288,6 +292,7 @@
<menu_item_check label="Işıklar" name="Lights"/>
<menu_item_check label="Çarpışma İskeleti" name="Collision Skeleton"/>
<menu_item_check label="Işın Yayını" name="Raycast"/>
+ <menu_item_check label="Rüzgar Vektörleri" name="Wind Vectors"/>
<menu_item_check label="İşleme Karmaşıklığı" name="rendercomplexity"/>
<menu_item_check label="Şekillendir" name="Sculpt"/>
</menu>
@@ -300,7 +305,6 @@
<menu_item_check label="Işıklandırma ve Gölgeler" name="Lighting and Shadows"/>
<menu_item_check label="Güneş/Ay/Projektörlerden Gelen Gölgeler" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO ve Gölge Yumuşatma" name="SSAO and Shadow Smoothing"/>
- <menu_item_check label="Küresel Aydınlatma (Deneysel)" name="Global Illumination"/>
<menu_item_check label="GL Hata Ayıklama" name="Debug GL"/>
<menu_item_check label="Ardışık Hata Ayıklama" name="Debug Pipeline"/>
<menu_item_check label="Otomatik Alfa Maskeleri (ertelenmiş)" name="Automatic Alpha Masks (deferred)"/>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 6908f6867f..631634aa7d 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -1110,8 +1110,13 @@ Arazinin satış bedeli sahibine geri ödenmez. Devredilen bir parsel satılırs
<notification name="DisplaySetToSafe">
Güvenli seçeneği seçtiğiniz için görüntüleme ayarları güvenli düzeye ayarlandı.
</notification>
- <notification name="DisplaySetToRecommended">
- Görüntüleme ayarları sistem yapılandırmanız için önerilen düzeye ayarlandı.
+ <notification name="DisplaySetToRecommendedGPUChange">
+ Grafik kartınız değiştiği için görüntü ayarları tavsiye edilen seviyelere ayarlandı
+önceki: &apos;[LAST_GPU]&apos;
+sonraki: &apos;[THIS_GPU]&apos;
+ </notification>
+ <notification name="DisplaySetToRecommendedFeatureChange">
+ İşleme alt sistemindeki bir değişiklik nedeniyle görüntü ayarları tavsiye edilen seviyelere ayarlandı.
</notification>
<notification name="ErrorMessage">
[ERROR_MESSAGE]
@@ -1431,7 +1436,7 @@ Güncellemeyi kurmak için [APP_NAME] uygulamasını yeniden başlatmalısınız
<usetemplate ignoretext="Nesneleri sahiplerine iade etmeden önce doğrulama iste" name="okcancelignore" notext="İptal" yestext="Tamam"/>
</notification>
<notification name="GroupLeaveConfirmMember">
- Şu anda [GROUP] grubunun bir üyesisiniz.
+ Şu anda &lt;nolink&gt;[GROUP]&lt;/nolink&gt; grubunun bir üyesisiniz.
Gruptan ayrılmak istiyor musunuz?
<usetemplate name="okcancelbuttons" notext="İptal" yestext="Tamam"/>
</notification>
@@ -1910,7 +1915,13 @@ Envanter öğesi/öğeleri taşınsın mı?
<usetemplate ignoretext="Çıkmadan önce doğrulama iste" name="okcancelignore" notext="Çıkma" yestext="Çık"/>
</notification>
<notification name="ConfirmRestoreToybox">
- Varsayılan düğmelerinizi ve araç çubuklarınızı geri yüklemek istediğinize emin misiniz?
+ Bu eylem, varsayılan düğmelerinizi ve araç çubuklarınızı geri yükleyecek.
+
+Bu eylemi geri alamazsınız.
+ <usetemplate name="okcancelbuttons" notext="İptal" yestext="Tamam"/>
+ </notification>
+ <notification name="ConfirmClearAllToybox">
+ Bu eylem ile tüm düğmeler araç kutusuna döner ve araç çubuklarınız boş olur.
Bu eylemi geri alamazsınız.
<usetemplate name="okcancelbuttons" notext="İptal" yestext="Tamam"/>
@@ -2119,10 +2130,10 @@ Bu adımda web tarayıcınızın başlatılacağına dikkat edin.
Konu: [SUBJECT], İleti: [MESSAGE]
</notification>
<notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; Çevrimiçi
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; çevrimiçi
</notification>
<notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; Çevrimdışı
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; çevrimdışı
</notification>
<notification name="AddSelfFriend">
Çok iyi biri olduğunuza eminiz fakat kendinizi arkadaş olarak ekleyemezsiniz.
@@ -2236,14 +2247,16 @@ Lütfen tek bir nesne seçin.
Arama kartınız reddedildi.
</notification>
<notification name="TeleportToLandmark">
- Ekranınızın sağ tarafındaki Yerler panelini açıp Yer İmleri sekmesini seçerek &apos;[NAME]&apos; gibi konumlara ışınlanabilirsiniz.
-Seçmek için herhangi bir yer iminin üzerini tıklatın ve ardından panelin en altındaki &apos;Işınla&apos; düğmesini tıklatın.
-(Yer iminin üzerini çift tıklatabilir veya sağ tıklayıp &apos;Işınla&apos;yı seçebilirsiniz.)
+ &apos;[NAME]&apos; gibi konumlara ışınlanmak için &quot;Yerler&quot; düğmesine tıklayın,
+ sonra açılan pencerede Yer İmleri sekmesini seçin. Herhangi bir
+ yer iminin üzerine tıklayarak bunu seçin ve ardından pencerenin en altındaki &apos;Işınla&apos; düğmesine tıklayın.
+ (Ayrıca yer imine çift tıklayabilir veya sağ tıklayarak
+ &apos;Işınla&apos; seçimini yapabilirsiniz.)
</notification>
<notification name="TeleportToPerson">
- Ekranınızın sağ tarafındaki İnsanlar panelini açarak &apos;[NAME]&apos; gibi Sakinler ile iletişim kurabilirsiniz.
-Sakini listeden seçin ve panelin altındaki &apos;Aİ&quot; düğmesini tıklatın.
-(Listede adlarını çift tıklatarak veya sağ tıklatıp &quot;Aİ&quot;yi seçerek de bunu yapabilirsiniz.)
+ &apos;[NAME]&apos; gibi sakinlerle bağlantıya geçmek için &quot;Kişiler&quot; düğmesine tıklayın, açılan pencereden bir Sakin seçin ve sonra
+ pencerenin altında &apos;Anlık İleti&quot; üzerine tıklayın.
+ (Listede adlarına çift tıklayarak veya sağ tıklayıp &quot;Anlık İleti&quot;yi seçerek de bunu yapabilirsiniz.)
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Sunucunun sınırları dışındaki arazi seçilemez.
@@ -2264,6 +2277,9 @@ Daha küçük bir arazi parçası seçmeyi deneyin.
<notification name="PaymentSent">
[MESSAGE]
</notification>
+ <notification name="PaymentFailure">
+ [MESSAGE]
+ </notification>
<notification name="EventNotification">
Etkinlik Bildirimi
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_skin.xml b/indra/newview/skins/default/xui/tr/panel_edit_skin.xml
index 33fb787e08..fdf75100ed 100644
--- a/indra/newview/skins/default/xui/tr/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_skin.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skin_panel">
<panel name="avatar_skin_color_panel">
- <texture_picker label="Baş Dövmeleri" name="Head Tattoos" tool_tip="Bir resim seçmek için tıklayın"/>
- <texture_picker label="Üst Gövde Dövmeleri" name="Upper Tattoos" tool_tip="Bir resim seçmek için tıklayın"/>
- <texture_picker label="Alt Gövde Dövmeleri" name="Lower Tattoos" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Baş" name="Head" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Üst gövde" name="Upper Body" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Alt gövde" name="Lower Body" tool_tip="Bir resim seçmek için tıklayın"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/tr/panel_postcard_message.xml b/indra/newview/skins/default/xui/tr/panel_postcard_message.xml
new file mode 100644
index 0000000000..2361f4c1c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_postcard_message.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_message">
+ <text name="to_label">
+ Kime:
+ </text>
+ <text name="name_label">
+ Kimden:
+ </text>
+ <text name="subject_label">
+ Konu:
+ </text>
+ <line_editor label="Konunuzu buraya yazın." name="subject_form"/>
+ <text name="msg_label">
+ İleti:
+ </text>
+ <text_editor name="msg_form">
+ İletinizi buraya yazın.
+ </text_editor>
+ <button label="İptal" name="cancel_btn"/>
+ <button label="Gönder" name="send_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_postcard_settings.xml b/indra/newview/skins/default/xui/tr/panel_postcard_settings.xml
new file mode 100644
index 0000000000..bce0b21b9a
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_postcard_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_settings">
+ <combo_box label="Çözünürlük" name="postcard_size_combo">
+ <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Özel" name="Custom"/>
+ </combo_box>
+ <layout_stack name="postcard_image_params_ls">
+ <layout_panel name="postcard_image_size_lp">
+ <spinner label="Genişlik" name="postcard_snapshot_width"/>
+ <spinner label="Yükseklik" name="postcard_snapshot_height"/>
+ <check_box label="Oranları koru" name="postcard_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="postcard_image_format_quality_lp">
+ <slider label="Görüntü kalitesi" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml
index f7f0698a31..9caf95a122 100644
--- a/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml
@@ -29,29 +29,5 @@
<check_box label="Aİ Sohbetleri" name="EnableIMChatPopups" tool_tip="Bir anlık ileti geldiğinde açılır pencereleri görmek için işaretle"/>
<spinner label="Yakındaki sohbet iletilerinin vurgulanma süresi:" name="nearby_toasts_lifetime"/>
<spinner label="Yakındaki sohbet iletilerinin sönme süresi:" name="nearby_toasts_fadingtime"/>
- <text name="translate_chb_label">
- Sohbet ederken makine çevirisi kullanılsın
- </text>
- <text name="translate_language_text">
- Sohbeti şu dile çevir:
- </text>
- <combo_box name="translate_language_combobox">
- <combo_box.item label="Sistem Varsayılanı" name="System Default Language"/>
- <combo_box.item label="İngilizce" name="English"/>
- <combo_box.item label="Dansk (Danca)" name="Danish"/>
- <combo_box.item label="Deutsch (Almanca)" name="German"/>
- <combo_box.item label="Español (İspanyolca)" name="Spanish"/>
- <combo_box.item label="Français (Fransızca)" name="French"/>
- <combo_box.item label="Italiano (İtalyanca)" name="Italian"/>
- <combo_box.item label="Magyar (Macarca)" name="Hungarian"/>
- <combo_box.item label="Nederlands (Flemenkçe)" name="Dutch"/>
- <combo_box.item label="Polski (Lehçe)" name="Polish"/>
- <combo_box.item label="Português (Portekizce)" name="Portugese"/>
- <combo_box.item label="Русский (Rusça)" name="Russian"/>
- <combo_box.item label="Türkçe (Türkçe)" name="Turkish"/>
- <combo_box.item label="Українська (Ukraynaca)" name="Ukrainian"/>
- <combo_box.item label="中文 (正體) (Çince)" name="Chinese"/>
- <combo_box.item label="日本語 (Japonca)" name="Japanese"/>
- <combo_box.item label="한국어 (Korece)" name="Korean"/>
- </combo_box>
+ <button label="Sohbet Çevirisi Ayarları" name="ok_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml b/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml
index 12c175b8f5..9d03d9b01d 100644
--- a/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml
@@ -15,7 +15,7 @@
Web:
</text>
<radio_group name="use_external_browser">
- <radio_item label="Tarayıcımı kullan (IE, Firefox, Safari)" name="external" tool_tip="Yardım, web bağlantıları vs. için sistemin varsayılan web tarayıcısını kullanın. Tam ekran çalıştırılıyorsa tavsiye edilmez." value="1"/>
+ <radio_item label="Tarayıcımı kullan (IE, Firefox, Safari)" name="external" tool_tip="Yardım, web bağlantıları vs. için sistemin varsayılan web tarayıcısını kullanın. Tam ekran çalıştırılıyorsa tavsiye edilmez." value="true"/>
<radio_item label="Yerleşik tarayıcıyı kullan" name="internal" tool_tip="Yardım, web bağlantıları vs. için dahili web tarayıcısını kullanın. Bu tarayıcı [APP_NAME] içerisinde yeni bir pencere olarak açılır." value=""/>
</radio_group>
<check_box initial_value="true" label="Eklentileri etkinleştir" name="browser_plugins_enabled"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml
new file mode 100644
index 0000000000..e3b22c639a
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_inventory">
+ <text name="title">
+ Envanterime Kaydet
+ </text>
+ <text name="hint_lbl">
+ Bir görüntüyü envanterinize kaydetmenin maliyeti L$[UPLOAD_COST] olur. Görüntünüzü bir doku olarak kaydetmek için kare formatlardan birini seçin.
+ </text>
+ <combo_box label="Çözünürlük" name="texture_size_combo">
+ <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
+ <combo_box.item label="Küçük (128x128)" name="Small(128x128)"/>
+ <combo_box.item label="Orta (256x256)" name="Medium(256x256)"/>
+ <combo_box.item label="Büyük (512x512)" name="Large(512x512)"/>
+ <combo_box.item label="Özel" name="Custom"/>
+ </combo_box>
+ <spinner label="Genişlik" name="inventory_snapshot_width"/>
+ <spinner label="Yükseklik" name="inventory_snapshot_height"/>
+ <check_box label="Oranları koru" name="inventory_keep_aspect_check"/>
+ <button label="İptal" name="cancel_btn"/>
+ <button label="Kaydet" name="save_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_local.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_local.xml
new file mode 100644
index 0000000000..87d7677d73
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_snapshot_local.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_local">
+ <text name="title">
+ Bilgisayarıma Kaydet
+ </text>
+ <combo_box label="Çözünürlük" name="local_size_combo">
+ <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
+ <combo_box.item label="320x240" name="320x240"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="1280x1024" name="1280x1024"/>
+ <combo_box.item label="1600x1200" name="1600x1200"/>
+ <combo_box.item label="Özel" name="Custom"/>
+ </combo_box>
+ <layout_stack name="local_image_params_ls">
+ <layout_panel name="local_image_size_lp">
+ <spinner label="Genişlik" name="local_snapshot_width"/>
+ <spinner label="Yükseklik" name="local_snapshot_height"/>
+ <check_box label="Oranları koru" name="local_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="local_image_format_quality_lp">
+ <combo_box label="Format" name="local_format_combo">
+ <combo_box.item label="PNG (Kayıpsız)" name="PNG"/>
+ <combo_box.item label="JPEG" name="JPEG"/>
+ <combo_box.item label="BMP (Kayıpsız)" name="BMP"/>
+ </combo_box>
+ <slider label="Görüntü kalitesi" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <button label="İptal" name="cancel_btn"/>
+ <flyout_button label="Kaydet" name="save_btn" tool_tip="Görüntüyü bir dosyaya kaydet">
+ <flyout_button.item label="Kaydet" name="save_item"/>
+ <flyout_button.item label="Farklı Kaydet..." name="saveas_item"/>
+ </flyout_button>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml
new file mode 100644
index 0000000000..fd2e85fce5
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_options">
+ <button label="Profil Akışımda Yayınla" name="save_to_profile_btn"/>
+ <button label="E-posta" name="save_to_email_btn"/>
+ <button label="Envanterime Kaydet (L$[AMOUNT])" name="save_to_inventory_btn"/>
+ <button label="Bilgisayarıma Kaydet" name="save_to_computer_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml
new file mode 100644
index 0000000000..e999678a0d
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_postcard">
+ <string name="default_subject">
+ SECOND_LIFE]&apos;dan posta kartı.
+ </string>
+ <string name="default_message">
+ Buna bakın!
+ </string>
+ <string name="upload_message">
+ Gönderiyor...
+ </string>
+ <text name="title">
+ E-posta
+ </text>
+ <button label="İleti" name="message_btn"/>
+ <button label="Ayarlar" name="settings_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_profile.xml
new file mode 100644
index 0000000000..334fd52a48
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_snapshot_profile.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_profile">
+ <text name="title">
+ Profil Akışımda Yayınla
+ </text>
+ <combo_box label="Çözünürlük" name="profile_size_combo">
+ <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="Özel" name="Custom"/>
+ </combo_box>
+ <layout_stack name="profile_image_params_ls">
+ <layout_panel name="profile_image_size_lp">
+ <spinner label="Genişlik" name="profile_snapshot_width"/>
+ <spinner label="Yükseklik" name="profile_snapshot_height"/>
+ <check_box label="Oranları koru" name="profile_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="profile_image_metadata_lp">
+ <text name="caption_label">
+ Resim yazısı:
+ </text>
+ <check_box initial_value="true" label="Konumu dahil et" name="add_location_cb"/>
+ </layout_panel>
+ </layout_stack>
+ <button label="İptal" name="cancel_btn"/>
+ <button label="Yayınla" name="post_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_status_bar.xml b/indra/newview/skins/default/xui/tr/panel_status_bar.xml
index 63726b94e2..81c304a5d8 100644
--- a/indra/newview/skins/default/xui/tr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_status_bar.xml
@@ -18,7 +18,7 @@
<panel name="balance_bg">
<text name="balance" tool_tip="L$ bakiyenizi yenilemek için buraya tıklayın" value="L$20"/>
<button label="L$ Satın Al" name="buyL" tool_tip="Daha fazla L$ satın almak için tıklayın"/>
- <button label="Alışveriş yap" name="goShop" tool_tip="Second Life Pazaryeri Aç"/>
+ <button label="Alışveriş yap" name="goShop" tool_tip="Second Life Pazaryeri Aç" width="95"/>
</panel>
<text name="TimeText" tool_tip="Geçerli zaman (Pasifik)">
24:00 AM PST
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index bf331dc3cf..0dbc9b0a0e 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -1211,7 +1211,7 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
Envanterinizde bu dokunun kopyası yok
</string>
<string name="InventoryInboxNoItems">
- Pazaryeri üzerinden satın alınan öğeler buraya teslim edilir.
+ Bir öğeyi satın aldığınızda veya başka bir şekilde edindiğinizde burada görünür; bunu envanterinizdeki bir klasöre sürükleyebilir veya tutmak istemiyorsanız silebilirsiniz.
</string>
<string name="MarketplaceURL">
http://marketplace.[DOMAIN_NAME]
@@ -1409,6 +1409,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="no_attachments">
Giyilen aksesuar yok
</string>
+ <string name="Attachments remain">
+ Aksesuarlar ([COUNT] yuva mevcut)
+ </string>
<string name="Buy">
Satın Al
</string>
@@ -1535,6 +1538,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="Right Pec">
Sağ Göğüs
</string>
+ <string name="Neck">
+ Boyun
+ </string>
+ <string name="Avatar Center">
+ Avatar Merkezi
+ </string>
<string name="Invalid Attachment">
Geçersiz Aksesuar Noktası
</string>
@@ -4027,6 +4036,18 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="you_paid_ldollars_no_name">
[REASON] L$[AMOUNT] ödediniz.
</string>
+ <string name="you_paid_failure_ldollars">
+ [REASON] [NAME]&apos;e L$[AMOUNT] ödeyemediniz.
+ </string>
+ <string name="you_paid_failure_ldollars_no_info">
+ L$[AMOUNT] ödeyemediniz.
+ </string>
+ <string name="you_paid_failure_ldollars_no_reason">
+ [NAME]&apos;e L$[AMOUNT] ödeyemediniz.
+ </string>
+ <string name="you_paid_failure_ldollars_no_name">
+ [REASON] L$[AMOUNT] ödeyemediniz.
+ </string>
<string name="for item">
[ITEM] için.
</string>
@@ -4437,6 +4458,12 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="ExternalEditorFailedToRun">
Harici düzenleyici çalışmadı.
</string>
+ <string name="TranslationFailed">
+ Çeviri başarılamadı: [REASON]
+ </string>
+ <string name="TranslationResponseParseError">
+ Çeviri yanıtı ayrıştırılırken hata meydana geldi.
+ </string>
<string name="Esc">
Esc
</string>
@@ -4819,7 +4846,7 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
Mini-harita
</string>
<string name="Command_Move_Label">
- Hareket Et
+ Yürü / koş / uç
</string>
<string name="Command_People_Label">
Kişiler
@@ -4846,10 +4873,10 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
Konuş
</string>
<string name="Command_View_Label">
- Görünüm
+ Kamera denetimleri
</string>
<string name="Command_Voice_Label">
- Yakındaki ses
+ Ses ayarları
</string>
<string name="Command_AboutLand_Tooltip">
Ziyaret ettiğiniz araziyle ilgili bilgi
@@ -4921,7 +4948,16 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
Kamera açısını değiştirmek
</string>
<string name="Command_Voice_Tooltip">
- Ses imkanına sahip yakındaki kişiler
+ Aramalar ve SL dünyası içinde size yakın kişiler için ses denetimleri
+ </string>
+ <string name="Toolbar_Bottom_Tooltip">
+ şu anda alt araç çubuğunuzda
+ </string>
+ <string name="Toolbar_Left_Tooltip">
+ şu anda sol araç çubuğunuzda
+ </string>
+ <string name="Toolbar_Right_Tooltip">
+ şu anda sağ araç çubuğunuzda
</string>
<string name="Retain%">
Koru %
@@ -4947,4 +4983,19 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="Normal">
Normal
</string>
+ <string name="snapshot_quality_very_low">
+ Çok Düşük
+ </string>
+ <string name="snapshot_quality_low">
+ Düşük
+ </string>
+ <string name="snapshot_quality_medium">
+ Orta
+ </string>
+ <string name="snapshot_quality_high">
+ Yüksek
+ </string>
+ <string name="snapshot_quality_very_high">
+ Çok Yüksek
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/tr/teleport_strings.xml b/indra/newview/skins/default/xui/tr/teleport_strings.xml
index c506bb8a58..62aaaf671f 100644
--- a/indra/newview/skins/default/xui/tr/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/tr/teleport_strings.xml
@@ -21,8 +21,8 @@ Hala ışınlanamıyorsanız, sorunu çözmek için lütfen çıkış yapıp otu
Bir dakika sonra tekrar deneyin.
</message>
<message name="NoHelpIslandTP">
-You cannot teleport back to Welcome Island.
-Go to &apos;Welcome Island Public&apos; to repeat the tutorial.
+ Karşılama Ada&apos;sına geri ışınlanamazsınız.
+Öğreticiyi tekrarlamak için &apos;Karşılama Ada&apos;sı Kamusal Alanı&apos;na gidin.
</message>
<message name="noaccess_tport">
Üzgünüz, bu ışınlanma hedef konumuna erişim hakkına sahip değilsiniz.
diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml
index f7be781cac..b6bb79bcbc 100644
--- a/indra/newview/skins/default/xui/zh/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml
@@ -20,8 +20,6 @@
<menu_item_call label="離開" name="Set Away"/>
<menu_item_call label="忙碌" name="Set Busy"/>
</menu>
- <menu_item_call label="要求 Admin 狀態" name="Request Admin Options"/>
- <menu_item_call label="離開 Admin 狀態" name="Leave Admin Options"/>
<menu_item_call label="結束退出 [APP_NAME]" name="Quit"/>
</menu>
<menu label="溝通" name="Communicate">
@@ -36,11 +34,10 @@
<menu_item_check label="搜尋" name="Search"/>
<menu_item_call label="拍攝快照" name="Take Snapshot"/>
<menu_item_call label="將此處記下地標" name="Create Landmark Here"/>
- <menu label="地點檔案" name="Land">
- <menu_item_call label="地點檔案" name="Place Profile"/>
- <menu_item_call label="關於土地" name="About Land"/>
- <menu_item_call label="地區 / 領地" name="Region/Estate"/>
- </menu>
+ <menu_item_separator/>
+ <menu_item_call label="地點檔案" name="Place Profile"/>
+ <menu_item_call label="關於土地" name="About Land"/>
+ <menu_item_call label="地區 / 領地" name="Region/Estate"/>
<menu_item_call label="購買這塊土地" name="Buy Land"/>
<menu_item_call label="我的土地" name="My Land"/>
<menu label="顯示" name="LandShow">
@@ -56,7 +53,7 @@
</menu>
<menu_item_call label="瞬間瞬間傳送回家" name="Teleport Home"/>
<menu_item_call label="設定家在此處" name="Set Home to Here"/>
- <menu label="太陽" name="Environment Settings">
+ <menu label="太陽" name="Sun">
<menu_item_call label="日出" name="Sunrise"/>
<menu_item_call label="中午" name="Noon"/>
<menu_item_call label="日落" name="Sunset"/>
@@ -154,22 +151,22 @@
<menu_item_check label="顯示第一人稱視角準星" name="ShowCrosshairs"/>
</menu>
<menu label="Rendering Types" name="Rendering Types">
- <menu_item_check label="簡單" name="Simple"/>
- <menu_item_check label="半透明" name="Alpha"/>
- <menu_item_check label="樹木" name="Tree"/>
- <menu_item_check label="化身" name="Character"/>
- <menu_item_check label="地表" name="SurfacePath"/>
- <menu_item_check label="天空" name="Sky"/>
- <menu_item_check label="水文" name="Water"/>
- <menu_item_check label="地面" name="Ground"/>
- <menu_item_check label="體積" name="Volume"/>
- <menu_item_check label="草地" name="Grass"/>
- <menu_item_check label="雲彩" name="Clouds"/>
- <menu_item_check label="粒子效果" name="Particles"/>
- <menu_item_check label="碰撞" name="Bump"/>
+ <menu_item_check label="簡單" name="Rendering Type Simple"/>
+ <menu_item_check label="半透明" name="Rendering Type Alpha"/>
+ <menu_item_check label="樹木" name="Rendering Type Tree"/>
+ <menu_item_check label="化身" name="Rendering Type Character"/>
+ <menu_item_check label="地表" name="Rendering Type Surface Patch"/>
+ <menu_item_check label="天空" name="Rendering Type Sky"/>
+ <menu_item_check label="水文" name="Rendering Type Water"/>
+ <menu_item_check label="地面" name="Rendering Type Ground"/>
+ <menu_item_check label="體積" name="Rendering Type Volume"/>
+ <menu_item_check label="草地" name="Rendering Type Grass"/>
+ <menu_item_check label="雲彩" name="Rendering Type Clouds"/>
+ <menu_item_check label="粒子效果" name="Rendering Type Particles"/>
+ <menu_item_check label="碰撞" name="Rendering Type Bump"/>
</menu>
<menu label="Rendering Features" name="Rendering Features">
- <menu_item_check label="UI" name="UI"/>
+ <menu_item_check label="UI" name="ToggleUI"/>
<menu_item_check label="Selected" name="Selected"/>
<menu_item_check label="Highlighted" name="Highlighted"/>
<menu_item_check label="Dynamic Textures" name="Dynamic Textures"/>
@@ -182,10 +179,7 @@
<menu_item_call label="清除群組快取資料" name="ClearGroupCache"/>
<menu_item_check label="滑鼠平滑移動" name="Mouse Smoothing"/>
<menu label="快速鍵" name="Shortcuts">
- <menu_item_call label="圖像(L$[COST])..." name="Upload Image"/>
- <menu_item_check label="搜尋" name="Search"/>
<menu_item_call label="釋出按鍵" name="Release Keys"/>
- <menu_item_call label="設定使用者界面大小至預設值" name="Set UI Size to Default"/>
<menu_item_check label="顯示進階選單 - 舊版捷徑" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="關閉視窗" name="Close Window"/>
<menu_item_call label="關閉全部視窗" name="Close All Windows"/>
@@ -194,13 +188,6 @@
<menu_item_check label="Joystick Flycam" name="Joystick Flycam"/>
<menu_item_call label="重設視角" name="Reset View"/>
<menu_item_call label="注視上一位聊天者" name="Look at Last Chatter"/>
- <menu label="選擇建造工具" name="Select Tool">
- <menu_item_call label="聚焦工具" name="Focus"/>
- <menu_item_call label="移動工具" name="Move"/>
- <menu_item_call label="編輯工具" name="Edit"/>
- <menu_item_call label="創造工具" name="Create"/>
- <menu_item_call label="土地工具" name="Land"/>
- </menu>
<menu_item_call label="Zoom In" name="Zoom In"/>
<menu_item_call label="Zoom Default" name="Zoom Default"/>
<menu_item_call label="Zoom Out" name="Zoom Out"/>
@@ -306,9 +293,8 @@
<menu_item_call label="開始錄製" name="Start Record"/>
<menu_item_call label="停止錄製" name="Stop Record"/>
</menu>
- <menu label="世界" name="World">
+ <menu label="世界" name="DevelopWorld">
<menu_item_check label="模擬器太陽設定覆蓋" name="Sim Sun Override"/>
- <menu_item_check label="Cheesy Beacon" name="Cheesy Beacon"/>
<menu_item_check label="固定天氣" name="Fixed Weather"/>
<menu_item_call label="傾印地區物件快取" name="Dump Region Object Cache"/>
</menu>
@@ -340,11 +326,11 @@
</menu>
<menu label="化身" name="Character">
<menu label="Grab Baked Texture" name="Grab Baked Texture">
- <menu_item_call label="Iris" name="Iris"/>
- <menu_item_call label="頭部" name="Head"/>
- <menu_item_call label="Upper Body" name="Upper Body"/>
- <menu_item_call label="Lower Body" name="Lower Body"/>
- <menu_item_call label="裙子" name="Skirt"/>
+ <menu_item_call label="Iris" name="Grab Iris"/>
+ <menu_item_call label="頭部" name="Grab Head"/>
+ <menu_item_call label="Upper Body" name="Grab Upper Body"/>
+ <menu_item_call label="Lower Body" name="Grab Lower Body"/>
+ <menu_item_call label="裙子" name="Grab Skirt"/>
</menu>
<menu label="Character Tests" name="Character Tests">
<menu_item_call label="Appearance To XML" name="Appearance To XML"/>
@@ -378,8 +364,8 @@
<menu_item_check label="Show Admin Menu" name="View Admin Options"/>
</menu>
<menu label="Admin" name="Admin">
- <menu label="Object">
- <menu_item_call label="取得副本" name="Take Copy"/>
+ <menu label="Object" name="AdminObject">
+ <menu_item_call label="取得副本" name="Admin Take Copy"/>
<menu_item_call label="強制擁有者為我" name="Force Owner To Me"/>
<menu_item_call label="Force Owner Permissive" name="Force Owner Permissive"/>
<menu_item_call label="刪除" name="Delete"/>
@@ -415,7 +401,7 @@
<menu_item_call label="身體物理" name="Physics"/>
<menu_item_call label="全部衣服" name="All Clothes"/>
</menu>
- <menu label="幫助" name="Help">
+ <menu label="幫助" name="DeprecatedHelp">
<menu_item_call label="林登官方部落格" name="Official Linden Blog"/>
<menu_item_call label="Scripting Portal" name="Scripting Portal"/>
<menu label="臭蟲回報" name="Bug Reporting">
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index 17ff6288a5..3fa8ff3f78 100644
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -1418,7 +1418,7 @@ We must restart [APP_NAME] to install the update.
<usetemplate ignoretext="在我退回物件給它們的擁有者前確認" name="okcancelignore" notext="取消" yestext="確定"/>
</notification>
<notification name="GroupLeaveConfirmMember">
- 你目前是 [GROUP] 群組的成員。
+ 你目前是 &lt;nolink&gt;[GROUP]&lt;/nolink&gt; 群組的成員。
是否要離開群組?
<usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/>
</notification>
diff --git a/indra/newview/skins/paths.xml b/indra/newview/skins/paths.xml
index e6d68488ea..3c0da041c7 100644
--- a/indra/newview/skins/paths.xml
+++ b/indra/newview/skins/paths.xml
@@ -1,4 +1,4 @@
-<paths>
+<paths>
<directory>
<subdir>xui</subdir>
<subdir>en</subdir>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 0931c4ec9b..d65d51ce32 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1025,41 +1025,27 @@ class Linux_i686Manifest(LinuxManifest):
super(Linux_i686Manifest, self).construct()
if self.prefix("../packages/lib/release", dst="lib"):
- self.path("libapr-1.so")
- self.path("libapr-1.so.0")
- self.path("libapr-1.so.0.4.2")
- self.path("libaprutil-1.so")
- self.path("libaprutil-1.so.0")
- self.path("libaprutil-1.so.0.3.10")
- self.path("libbreakpad_client.so.0.0.0")
- self.path("libbreakpad_client.so.0")
- self.path("libbreakpad_client.so")
+ self.path("libapr-1.so*")
+ self.path("libaprutil-1.so*")
+ self.path("libbreakpad_client.so*")
self.path("libcollada14dom.so")
- self.path("libdb-5.1.so")
- self.path("libdb-5.so")
- self.path("libdb.so")
- self.path("libcrypto.so.1.0.0")
- self.path("libexpat.so.1.5.2")
+ self.path("libdb*.so")
+ self.path("libcrypto.so.*")
+ self.path("libexpat.so.*")
self.path("libssl.so.1.0.0")
self.path("libglod.so")
self.path("libminizip.so")
- self.path("libuuid.so")
- self.path("libuuid.so.16")
- self.path("libuuid.so.16.0.22")
- self.path("libSDL-1.2.so.0.11.3")
- self.path("libdirectfb-1.4.so.5.0.4")
- self.path("libfusion-1.4.so.5.0.4")
- self.path("libdirect-1.4.so.5.0.4")
- self.path("libopenjpeg.so.1.4.0")
- self.path("libopenjpeg.so.1")
- self.path("libopenjpeg.so")
+ self.path("libuuid.so*")
+ self.path("libSDL-1.2.so.*")
+ self.path("libdirectfb-1.*.so.*")
+ self.path("libfusion-1.*.so.*")
+ self.path("libdirect-1.*.so.*")
+ self.path("libopenjpeg.so*")
self.path("libalut.so")
self.path("libopenal.so", "libopenal.so.1")
self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname
- self.path("libfontconfig.so.1.4.4")
- self.path("libtcmalloc.so", "libtcmalloc.so") #formerly called google perf tools
- self.path("libtcmalloc.so.0", "libtcmalloc.so.0") #formerly called google perf tools
- self.path("libtcmalloc.so.0.1.0", "libtcmalloc.so.0.1.0") #formerly called google perf tools
+ self.path("libfontconfig.so.*")
+ self.path("libtcmalloc.so*") #formerly called google perf tools
try:
self.path("libfmod-3.75.so")
pass
diff --git a/indra/test/catch_and_store_what_in.h b/indra/test/catch_and_store_what_in.h
new file mode 100644
index 0000000000..59f8cc0085
--- /dev/null
+++ b/indra/test/catch_and_store_what_in.h
@@ -0,0 +1,86 @@
+/**
+ * @file catch_and_store_what_in.h
+ * @author Nat Goodspeed
+ * @date 2012-02-15
+ * @brief CATCH_AND_STORE_WHAT_IN() macro
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_CATCH_AND_STORE_WHAT_IN_H)
+#define LL_CATCH_AND_STORE_WHAT_IN_H
+
+/**
+ * Idiom useful for test programs: catch an expected exception, store its
+ * what() string in a specified std::string variable. From there the caller
+ * can do things like:
+ * @code
+ * ensure("expected exception not thrown", ! string.empty());
+ * @endcode
+ * or
+ * @code
+ * ensure_contains("exception doesn't mention blah", string, "blah");
+ * @endcode
+ * etc.
+ *
+ * The trouble is that when linking to a dynamic libllcommon.so on Linux, we
+ * generally fail to catch the specific exception. Oddly, we can catch it as
+ * std::runtime_error and validate its typeid().name(), so we do -- but that's
+ * a lot of boilerplate per test. Encapsulate with this macro. Usage:
+ *
+ * @code
+ * std::string threw;
+ * try
+ * {
+ * some_call_that_should_throw_Foo();
+ * }
+ * CATCH_AND_STORE_WHAT_IN(threw, Foo)
+ * ensure("some_call_that_should_throw_Foo() didn't throw", ! threw.empty());
+ * @endcode
+ */
+#define CATCH_AND_STORE_WHAT_IN(THREW, EXCEPTION) \
+catch (const EXCEPTION& ex) \
+{ \
+ (THREW) = ex.what(); \
+} \
+CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION)
+
+#ifndef LL_LINUX
+#define CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION) \
+ /* only needed on Linux */
+#else // LL_LINUX
+
+#define CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION) \
+catch (const std::runtime_error& ex) \
+{ \
+ /* This clause is needed on Linux, on the viewer side, because */ \
+ /* the exception isn't caught by catch (const EXCEPTION&). */ \
+ /* But if the expected exception was thrown, allow the test to */ \
+ /* succeed anyway. Not sure how else to handle this odd case. */ \
+ if (std::string(typeid(ex).name()) == typeid(EXCEPTION).name()) \
+ { \
+ /* std::cerr << "Caught " << typeid(ex).name() */ \
+ /* << " with Linux workaround" << std::endl; */ \
+ (THREW) = ex.what(); \
+ /*std::cout << ex.what() << std::endl;*/ \
+ } \
+ else \
+ { \
+ /* We don't even recognize this exception. Let it propagate */ \
+ /* out to TUT to fail the test. */ \
+ throw; \
+ } \
+} \
+catch (...) \
+{ \
+ std::cerr << "Failed to catch expected exception " \
+ << #EXCEPTION << "!" << std::endl; \
+ /* This indicates a problem in the test that should be addressed. */ \
+ throw; \
+}
+
+#endif // LL_LINUX
+
+#endif /* ! defined(LL_CATCH_AND_STORE_WHAT_IN_H) */
diff --git a/indra/test/llevents_tut.cpp b/indra/test/llevents_tut.cpp
index 4699bb1827..a9114075fc 100644
--- a/indra/test/llevents_tut.cpp
+++ b/indra/test/llevents_tut.cpp
@@ -49,46 +49,12 @@
#include <boost/assign/list_of.hpp>
// other Linden headers
#include "lltut.h"
+#include "catch_and_store_what_in.h"
#include "stringize.h"
#include "tests/listener.h"
using boost::assign::list_of;
-#ifdef LL_LINUX
-#define CATCH_MISSED_LINUX_EXCEPTION(exception, threw) \
-catch (const std::runtime_error& ex) \
-{ \
- /* This clause is needed on Linux, on the viewer side, because the */ \
- /* exception isn't caught by the clause above. Warn the user... */ \
- std::cerr << "Failed to catch " << typeid(ex).name() << std::endl; \
- /* But if the expected exception was thrown, allow the test to */ \
- /* succeed anyway. Not sure how else to handle this odd case. */ \
- /* This approach is also used in llsdmessage_test.cpp. */ \
- if (std::string(typeid(ex).name()) == typeid(exception).name()) \
- { \
- threw = ex.what(); \
- /*std::cout << ex.what() << std::endl;*/ \
- } \
- else \
- { \
- /* We don't even recognize this exception. Let it propagate */ \
- /* out to TUT to fail the test. */ \
- throw; \
- } \
-} \
-catch (...) \
-{ \
- std::cerr << "Utterly failed to catch expected exception " << #exception << "!" << \
- std::endl; \
- /* This indicates a problem in the test that should be addressed. */ \
- throw; \
-}
-
-#else // LL_LINUX
-#define CATCH_MISSED_LINUX_EXCEPTION(exception, threw) \
- /* Not needed on other platforms */
-#endif // LL_LINUX
-
template<typename T>
T make(const T& value)
{
@@ -178,11 +144,7 @@ void events_object::test<1>()
per_frame.listen(listener0.getName(), // note bug, dup name
boost::bind(&Listener::call, boost::ref(listener1), _1));
}
- catch (const LLEventPump::DupListenerName& e)
- {
- threw = e.what();
- }
- CATCH_MISSED_LINUX_EXCEPTION(LLEventPump::DupListenerName, threw)
+ CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupListenerName)
ensure_equals(threw,
std::string("DupListenerName: "
"Attempt to register duplicate listener name '") +
@@ -354,7 +316,6 @@ void events_object::test<7>()
{
set_test_name("listener dependency order");
typedef LLEventPump::NameList NameList;
- typedef Collect::StringList StringList;
LLEventPump& button(pumps.obtain("button"));
Collect collector;
button.listen("Mary",
@@ -368,7 +329,7 @@ void events_object::test<7>()
button.listen("spot",
boost::bind(&Collect::add, boost::ref(collector), "spot", _1));
button.post(1);
- ensure_equals(collector.result, make<StringList>(list_of("spot")("checked")("Mary")));
+ ensure_equals(collector.result, make<StringVec>(list_of("spot")("checked")("Mary")));
collector.clear();
button.stopListening("Mary");
button.listen("Mary",
@@ -377,7 +338,7 @@ void events_object::test<7>()
// now "Mary" must come before "spot"
make<NameList>(list_of("spot")));
button.post(2);
- ensure_equals(collector.result, make<StringList>(list_of("Mary")("spot")("checked")));
+ ensure_equals(collector.result, make<StringVec>(list_of("Mary")("spot")("checked")));
collector.clear();
button.stopListening("spot");
std::string threw;
@@ -388,12 +349,7 @@ void events_object::test<7>()
// after "Mary" and "checked" -- whoops!
make<NameList>(list_of("Mary")("checked")));
}
- catch (const LLEventPump::Cycle& e)
- {
- threw = e.what();
- // std::cout << "Caught: " << e.what() << '\n';
- }
- CATCH_MISSED_LINUX_EXCEPTION(LLEventPump::Cycle, threw)
+ CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::Cycle)
// Obviously the specific wording of the exception text can
// change; go ahead and change the test to match.
// Establish that it contains:
@@ -416,7 +372,7 @@ void events_object::test<7>()
boost::bind(&Collect::add, boost::ref(collector), "shoelaces", _1),
make<NameList>(list_of("checked")));
button.post(3);
- ensure_equals(collector.result, make<StringList>(list_of("Mary")("checked")("yellow")("shoelaces")));
+ ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces")));
collector.clear();
threw.clear();
try
@@ -426,12 +382,7 @@ void events_object::test<7>()
make<NameList>(list_of("shoelaces")),
make<NameList>(list_of("yellow")));
}
- catch (const LLEventPump::OrderChange& e)
- {
- threw = e.what();
- // std::cout << "Caught: " << e.what() << '\n';
- }
- CATCH_MISSED_LINUX_EXCEPTION(LLEventPump::OrderChange, threw)
+ CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::OrderChange)
// Same remarks about the specific wording of the exception. Just
// ensure that it contains enough information to clarify the
// problem and what must be done to resolve it.
@@ -443,7 +394,7 @@ void events_object::test<7>()
ensure_contains("old order", threw, "was: Mary, checked, yellow, shoelaces");
ensure_contains("new order", threw, "now: Mary, checked, shoelaces, of, yellow");
button.post(4);
- ensure_equals(collector.result, make<StringList>(list_of("Mary")("checked")("yellow")("shoelaces")));
+ ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces")));
}
template<> template<>
@@ -459,12 +410,7 @@ void events_object::test<8>()
// then another with a duplicate name.
LLEventStream bob2("bob");
}
- catch (const LLEventPump::DupPumpName& e)
- {
- threw = e.what();
- // std::cout << "Caught: " << e.what() << '\n';
- }
- CATCH_MISSED_LINUX_EXCEPTION(LLEventPump::DupPumpName, threw)
+ CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupPumpName)
ensure("Caught DupPumpName", !threw.empty());
} // delete first 'bob'
LLEventStream bob("bob"); // should work, previous one unregistered
@@ -505,11 +451,7 @@ void events_object::test<9>()
LLListenerOrPumpName empty;
empty(17);
}
- catch (const LLListenerOrPumpName::Empty& e)
- {
- threw = e.what();
- }
- CATCH_MISSED_LINUX_EXCEPTION(LLListenerOrPumpName::Empty, threw)
+ CATCH_AND_STORE_WHAT_IN(threw, LLListenerOrPumpName::Empty)
ensure("threw Empty", !threw.empty());
}
diff --git a/indra/test/manageapr.h b/indra/test/manageapr.h
new file mode 100644
index 0000000000..2452fb6ae4
--- /dev/null
+++ b/indra/test/manageapr.h
@@ -0,0 +1,46 @@
+/**
+ * @file manageapr.h
+ * @author Nat Goodspeed
+ * @date 2012-01-13
+ * @brief ManageAPR class for simple test programs
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_MANAGEAPR_H)
+#define LL_MANAGEAPR_H
+
+#include "llapr.h"
+#include <boost/noncopyable.hpp>
+
+/**
+ * Declare a static instance of this class for dead-simple ll_init_apr() at
+ * program startup, ll_cleanup_apr() at termination. This is recommended for
+ * use only with simple test programs. Once you start introducing static
+ * instances of other classes that depend on APR already being initialized,
+ * the indeterminate static-constructor-order problem rears its ugly head.
+ */
+class ManageAPR: public boost::noncopyable
+{
+public:
+ ManageAPR()
+ {
+ ll_init_apr();
+ }
+
+ ~ManageAPR()
+ {
+ ll_cleanup_apr();
+ }
+
+ static std::string strerror(apr_status_t rv)
+ {
+ char errbuf[256];
+ apr_strerror(rv, errbuf, sizeof(errbuf));
+ return errbuf;
+ }
+};
+
+#endif /* ! defined(LL_MANAGEAPR_H) */
diff --git a/indra/test/namedtempfile.h b/indra/test/namedtempfile.h
new file mode 100644
index 0000000000..aa7058b111
--- /dev/null
+++ b/indra/test/namedtempfile.h
@@ -0,0 +1,114 @@
+/**
+ * @file namedtempfile.h
+ * @author Nat Goodspeed
+ * @date 2012-01-13
+ * @brief NamedTempFile class for tests that need disk files as fixtures.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_NAMEDTEMPFILE_H)
+#define LL_NAMEDTEMPFILE_H
+
+#include "llapr.h"
+#include "apr_file_io.h"
+#include <string>
+#include <boost/function.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+#include <boost/noncopyable.hpp>
+#include <iostream>
+#include <sstream>
+
+/**
+ * Create a text file with specified content "somewhere in the
+ * filesystem," cleaning up when it goes out of scope.
+ */
+class NamedTempFile: public boost::noncopyable
+{
+public:
+ NamedTempFile(const std::string& pfx, const std::string& content, apr_pool_t* pool=gAPRPoolp):
+ mPool(pool)
+ {
+ createFile(pfx, boost::lambda::_1 << content);
+ }
+
+ // Disambiguate when passing string literal
+ NamedTempFile(const std::string& pfx, const char* content, apr_pool_t* pool=gAPRPoolp):
+ mPool(pool)
+ {
+ createFile(pfx, boost::lambda::_1 << content);
+ }
+
+ // Function that accepts an ostream ref and (presumably) writes stuff to
+ // it, e.g.:
+ // (boost::lambda::_1 << "the value is " << 17 << '\n')
+ typedef boost::function<void(std::ostream&)> Streamer;
+
+ NamedTempFile(const std::string& pfx, const Streamer& func, apr_pool_t* pool=gAPRPoolp):
+ mPool(pool)
+ {
+ createFile(pfx, func);
+ }
+
+ ~NamedTempFile()
+ {
+ ll_apr_assert_status(apr_file_remove(mPath.c_str(), mPool));
+ }
+
+ std::string getName() const { return mPath; }
+
+ void peep()
+ {
+ std::cout << "File '" << mPath << "' contains:\n";
+ std::ifstream reader(mPath.c_str());
+ std::string line;
+ while (std::getline(reader, line))
+ std::cout << line << '\n';
+ std::cout << "---\n";
+ }
+
+private:
+ void createFile(const std::string& pfx, const Streamer& func)
+ {
+ // Create file in a temporary place.
+ const char* tempdir = NULL;
+ ll_apr_assert_status(apr_temp_dir_get(&tempdir, mPool));
+
+ // Construct a temp filename template in that directory.
+ char *tempname = NULL;
+ ll_apr_assert_status(apr_filepath_merge(&tempname,
+ tempdir,
+ (pfx + "XXXXXX").c_str(),
+ 0,
+ mPool));
+
+ // Create a temp file from that template.
+ apr_file_t* fp = NULL;
+ ll_apr_assert_status(apr_file_mktemp(&fp,
+ tempname,
+ APR_CREATE | APR_WRITE | APR_EXCL,
+ mPool));
+ // apr_file_mktemp() alters tempname with the actual name. Not until
+ // now is it valid to capture as our mPath.
+ mPath = tempname;
+
+ // Write desired content.
+ std::ostringstream out;
+ // Stream stuff to it.
+ func(out);
+
+ std::string data(out.str());
+ apr_size_t writelen(data.length());
+ ll_apr_assert_status(apr_file_write(fp, data.c_str(), &writelen));
+ ll_apr_assert_status(apr_file_close(fp));
+ llassert_always(writelen == data.length());
+ }
+
+ std::string mPath;
+ apr_pool_t* mPool;
+};
+
+#endif /* ! defined(LL_NAMEDTEMPFILE_H) */
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index ffdb0cb976..1adcfb6f45 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -37,6 +37,7 @@
#include "linden_common.h"
#include "llerrorcontrol.h"
#include "lltut.h"
+#include "stringize.h"
#include "apr_pools.h"
#include "apr_getopt.h"
@@ -53,6 +54,21 @@
#include <gtest/gtest.h>
#endif
+#if LL_MSVC
+#pragma warning (push)
+#pragma warning (disable : 4702) // warning C4702: unreachable code
+#endif
+#include <boost/iostreams/tee.hpp>
+#include <boost/iostreams/stream.hpp>
+#if LL_MSVC
+#pragma warning (pop)
+#endif
+
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
+
namespace tut
{
std::string sSourceDir;
@@ -69,8 +85,24 @@ public:
mPassedTests(0),
mFailedTests(0),
mSkippedTests(0),
- mStream(stream)
+ // By default, capture a shared_ptr to std::cout, with a no-op "deleter"
+ // so that destroying the shared_ptr makes no attempt to delete std::cout.
+ mStream(boost::shared_ptr<std::ostream>(&std::cout, boost::lambda::_1))
{
+ if (stream)
+ {
+ // We want a boost::iostreams::tee_device that will stream to two
+ // std::ostreams.
+ typedef boost::iostreams::tee_device<std::ostream, std::ostream> TeeDevice;
+ // More than that, though, we want an actual stream using that
+ // device.
+ typedef boost::iostreams::stream<TeeDevice> TeeStream;
+ // Allocate and assign in two separate steps, per Herb Sutter.
+ // (Until we turn on C++11 support, have to wrap *stream with
+ // boost::ref() due to lack of perfect forwarding.)
+ boost::shared_ptr<std::ostream> pstream(new TeeStream(std::cout, boost::ref(*stream)));
+ mStream = pstream;
+ }
}
~LLTestCallback()
@@ -94,7 +126,10 @@ public:
{
++mTotalTests;
std::ostringstream out;
- out << "[" << tr.group << ", " << tr.test << "] ";
+ out << "[" << tr.group << ", " << tr.test;
+ if (! tr.name.empty())
+ out << ": " << tr.name;
+ out << "] ";
switch(tr.result)
{
case tut::test_result::ok:
@@ -123,56 +158,43 @@ public:
break;
default:
++mFailedTests;
- out << "unknown";
+ out << "unknown (tr.result == " << tr.result << ")";
}
if(mVerboseMode || (tr.result != tut::test_result::ok))
{
+ *mStream << out.str();
if(!tr.message.empty())
{
- out << ": '" << tr.message << "'";
+ *mStream << ": '" << tr.message << "'";
}
- if (mStream)
- {
- *mStream << out.str() << std::endl;
- }
-
- std::cout << out.str() << std::endl;
+ *mStream << std::endl;
}
}
- virtual void run_completed()
- {
- if (mStream)
- {
- run_completed_(*mStream);
- }
- run_completed_(std::cout);
- }
-
virtual int getFailedTests() const { return mFailedTests; }
- virtual void run_completed_(std::ostream &stream)
+ virtual void run_completed()
{
- stream << "\tTotal Tests:\t" << mTotalTests << std::endl;
- stream << "\tPassed Tests:\t" << mPassedTests;
+ *mStream << "\tTotal Tests:\t" << mTotalTests << std::endl;
+ *mStream << "\tPassed Tests:\t" << mPassedTests;
if (mPassedTests == mTotalTests)
{
- stream << "\tYAY!! \\o/";
+ *mStream << "\tYAY!! \\o/";
}
- stream << std::endl;
+ *mStream << std::endl;
if (mSkippedTests > 0)
{
- stream << "\tSkipped known failures:\t" << mSkippedTests
+ *mStream << "\tSkipped known failures:\t" << mSkippedTests
<< std::endl;
}
if(mFailedTests > 0)
{
- stream << "*********************************" << std::endl;
- stream << "Failed Tests:\t" << mFailedTests << std::endl;
- stream << "Please report or fix the problem." << std::endl;
- stream << "*********************************" << std::endl;
+ *mStream << "*********************************" << std::endl;
+ *mStream << "Failed Tests:\t" << mFailedTests << std::endl;
+ *mStream << "Please report or fix the problem." << std::endl;
+ *mStream << "*********************************" << std::endl;
}
}
@@ -182,7 +204,7 @@ protected:
int mPassedTests;
int mFailedTests;
int mSkippedTests;
- std::ostream *mStream;
+ boost::shared_ptr<std::ostream> mStream;
};
// TeamCity specific class which emits service messages
@@ -192,84 +214,111 @@ class LLTCTestCallback : public LLTestCallback
{
public:
LLTCTestCallback(bool verbose_mode, std::ostream *stream) :
- LLTestCallback(verbose_mode, stream),
- mTCStream()
+ LLTestCallback(verbose_mode, stream)
{
}
~LLTCTestCallback()
{
- }
+ }
virtual void group_started(const std::string& name) {
LLTestCallback::group_started(name);
- mTCStream << "\n##teamcity[testSuiteStarted name='" << name << "']" << std::endl;
+ std::cout << "\n##teamcity[testSuiteStarted name='" << escape(name) << "']" << std::endl;
}
virtual void group_completed(const std::string& name) {
LLTestCallback::group_completed(name);
- mTCStream << "##teamcity[testSuiteFinished name='" << name << "']" << std::endl;
+ std::cout << "##teamcity[testSuiteFinished name='" << escape(name) << "']" << std::endl;
}
virtual void test_completed(const tut::test_result& tr)
{
+ std::string testname(STRINGIZE(tr.group << "." << tr.test));
+ if (! tr.name.empty())
+ {
+ testname.append(":");
+ testname.append(tr.name);
+ }
+ testname = escape(testname);
+
+ // Sadly, tut::callback doesn't give us control at test start; have to
+ // backfill start message into TC output.
+ std::cout << "##teamcity[testStarted name='" << testname << "']" << std::endl;
+
+ // now forward call to base class so any output produced there is in
+ // the right TC context
LLTestCallback::test_completed(tr);
switch(tr.result)
{
case tut::test_result::ok:
- mTCStream << "##teamcity[testStarted name='" << tr.group << "." << tr.test << "']" << std::endl;
- mTCStream << "##teamcity[testFinished name='" << tr.group << "." << tr.test << "']" << std::endl;
break;
+
case tut::test_result::fail:
- mTCStream << "##teamcity[testStarted name='" << tr.group << "." << tr.test << "']" << std::endl;
- mTCStream << "##teamcity[testFailed name='" << tr.group << "." << tr.test << "' message='" << tr.message << "']" << std::endl;
- mTCStream << "##teamcity[testFinished name='" << tr.group << "." << tr.test << "']" << std::endl;
- break;
case tut::test_result::ex:
- mTCStream << "##teamcity[testStarted name='" << tr.group << "." << tr.test << "']" << std::endl;
- mTCStream << "##teamcity[testFailed name='" << tr.group << "." << tr.test << "' message='" << tr.message << "']" << std::endl;
- mTCStream << "##teamcity[testFinished name='" << tr.group << "." << tr.test << "']" << std::endl;
- break;
case tut::test_result::warn:
- mTCStream << "##teamcity[testStarted name='" << tr.group << "." << tr.test << "']" << std::endl;
- mTCStream << "##teamcity[testFailed name='" << tr.group << "." << tr.test << "' message='" << tr.message << "']" << std::endl;
- mTCStream << "##teamcity[testFinished name='" << tr.group << "." << tr.test << "']" << std::endl;
- break;
case tut::test_result::term:
- mTCStream << "##teamcity[testStarted name='" << tr.group << "." << tr.test << "']" << std::endl;
- mTCStream << "##teamcity[testFailed name='" << tr.group << "." << tr.test << "' message='" << tr.message << "']" << std::endl;
- mTCStream << "##teamcity[testFinished name='" << tr.group << "." << tr.test << "']" << std::endl;
+ std::cout << "##teamcity[testFailed name='" << testname
+ << "' message='" << escape(tr.message) << "']" << std::endl;
break;
+
case tut::test_result::skip:
- mTCStream << "##teamcity[testStarted name='" << tr.group << "." << tr.test << "']" << std::endl;
- mTCStream << "##teamcity[testIgnored name='" << tr.group << "." << tr.test << "']" << std::endl;
- mTCStream << "##teamcity[testFinished name='" << tr.group << "." << tr.test << "']" << std::endl;
+ std::cout << "##teamcity[testIgnored name='" << testname << "']" << std::endl;
break;
+
default:
break;
}
+ std::cout << "##teamcity[testFinished name='" << testname << "']" << std::endl;
}
- virtual void run_completed()
- {
- LLTestCallback::run_completed();
-
- // dump the TC reporting results to cout
- tc_run_completed_(std::cout);
- }
-
- virtual void tc_run_completed_(std::ostream &stream)
+ static std::string escape(const std::string& str)
{
-
- // dump the TC reporting results to cout
- stream << mTCStream.str() << std::endl;
+ // Per http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ServiceMessages
+ std::string result;
+ BOOST_FOREACH(char c, str)
+ {
+ switch (c)
+ {
+ case '\'':
+ result.append("|'");
+ break;
+ case '\n':
+ result.append("|n");
+ break;
+ case '\r':
+ result.append("|r");
+ break;
+/*==========================================================================*|
+ // These are not possible 'char' values from a std::string.
+ case '\u0085': // next line
+ result.append("|x");
+ break;
+ case '\u2028': // line separator
+ result.append("|l");
+ break;
+ case '\u2029': // paragraph separator
+ result.append("|p");
+ break;
+|*==========================================================================*/
+ case '|':
+ result.append("||");
+ break;
+ case '[':
+ result.append("|[");
+ break;
+ case ']':
+ result.append("|]");
+ break;
+ default:
+ result.push_back(c);
+ break;
+ }
+ }
+ return result;
}
-
-protected:
- std::ostringstream mTCStream;
-
};
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index e88d1bf811..19ac418e9e 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -39,7 +39,7 @@
#include "llsdserialize.h"
#include "llthread.h"
#include "llupdaterservice.h"
-
+#include "llcurl.h"
class LLUpdateDownloader::Implementation:
public LLThread
@@ -198,13 +198,19 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client &
LLUpdateDownloader::Implementation::~Implementation()
{
- if(isDownloading()) {
+ if(isDownloading())
+ {
cancel();
shutdown();
- } else {
+ }
+ else
+ {
; // No op.
}
- if(mCurl) curl_easy_cleanup(mCurl);
+ if(mCurl)
+ {
+ LLCurl::deleteEasyHandle(mCurl);
+ }
}
@@ -406,9 +412,12 @@ void LLUpdateDownloader::Implementation::run(void)
void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader)
{
- if(mCurl == 0) {
- mCurl = curl_easy_init();
- } else {
+ if(mCurl == 0)
+ {
+ mCurl = LLCurl::newEasyHandle();
+ }
+ else
+ {
curl_easy_reset(mCurl);
}
diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
index c7b70c2de8..2f87d59373 100644
--- a/indra/viewer_components/updater/llupdateinstaller.cpp
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -26,10 +26,10 @@
#include "linden_common.h"
#include <apr_file_io.h>
#include "llapr.h"
-#include "llprocesslauncher.h"
+#include "llprocess.h"
#include "llupdateinstaller.h"
#include "lldir.h"
-
+#include "llsd.h"
#if defined(LL_WINDOWS)
#pragma warning(disable: 4702) // disable 'unreachable code' so we can use lexical_cast (really!).
@@ -78,15 +78,13 @@ int ll_install_update(std::string const & script,
llinfos << "UpdateInstaller: installing " << updatePath << " using " <<
actualScriptPath << LL_ENDL;
- LLProcessLauncher launcher;
- launcher.setExecutable(actualScriptPath);
- launcher.addArgument(updatePath);
- launcher.addArgument(ll_install_failed_marker_path().c_str());
- launcher.addArgument(boost::lexical_cast<std::string>(required));
- int result = launcher.launch();
- launcher.orphan();
-
- return result;
+ LLProcess::Params params;
+ params.executable = actualScriptPath;
+ params.args.add(updatePath);
+ params.args.add(ll_install_failed_marker_path());
+ params.args.add(boost::lexical_cast<std::string>(required));
+ params.autokill = false;
+ return LLProcess::create(params)? 0 : -1;
}